解决多线程安全方式:
sychronized: jvm维护,隐式锁
1. 同步代码块
2. 同步方法
3. 同步锁Lock jdk1.5以后, 上锁以后必须unlock[在finally]
案例:买票代码
1.1. 问题代码:
package com.denganzhi.pp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main2 {
public static void main(String[] args) {
AtomicDemo auAtomicDemo=new AtomicDemo();
Thread thread=null;
for (int i = 0; i < 10; i++) {
thread=new Thread(auAtomicDemo);
thread.setName("线程:"+i );
thread.start();
}
}
}
class AtomicDemo implements Runnable{
// 还 剩下 10 张票 ,10个人来 抢票
private int num=10;
Lock lock=new ReentrantLock();
@Override
public void run() {
// TODO Auto-generated method stub
//lock.lock(); // 上锁
try {
Thread.sleep(50);
int num=getSerialNumber();
if(num <= 0){
System.err.println(Thread.currentThread().getName() +" 没有抢到火车票");
}else{
System.out.println(Thread.currentThread().getName() +" 抢到第" + num + "张火车票");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//lock.unlock(); //释放锁
}
}
public int getSerialNumber() {
return num--;
}
}
运行结果: 一张火车票被多个人抢到,数据错误
线程:7 抢到第10张火车票
线程:8 抢到第7张火车票
线程:4 抢到第9张火车票
线程:3 抢到第9张火车票
线程:5 抢到第10张火车票
线程:0 抢到第8张火车票
线程:2 抢到第8张火车票
线程:1 抢到第8张火车票
线程:9 抢到第10张火车票
线程:6 抢到第10张火车票
3. 同步锁Lock jdk1.5以后, 上锁以后必须unlock[在finally]
package com.denganzhi.pp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main2 {
public static void main(String[] args) {
AtomicDemo auAtomicDemo=new AtomicDemo();
Thread thread=null;
for (int i = 0; i < 10; i++) {
thread=new Thread(auAtomicDemo);
thread.setName("线程:"+i );
thread.start();
}
}
}
class AtomicDemo implements Runnable{
// 还 剩下 10 张票 ,10个人来 抢票
private int num=10;
Lock lock=new ReentrantLock();
@Override
public void run() {
// TODO Auto-generated method stub
lock.lock(); // 上锁
try {
Thread.sleep(50);
int num=getSerialNumber();
if(num <= 0){
System.err.println(Thread.currentThread().getName() +" 没有抢到火车票");
}else{
System.out.println(Thread.currentThread().getName() +" 抢到第" + num + "张火车票");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock(); //释放锁
}
}
public int getSerialNumber() {
return num--;
}
}
正确输出结果:
线程:0 抢到第10张火车票
线程:1 抢到第9张火车票
线程:2 抢到第8张火车票
线程:3 抢到第7张火车票
线程:4 抢到第6张火车票
线程:5 抢到第5张火车票
线程:6 抢到第4张火车票
线程:7 抢到第3张火车票
线程:8 抢到第2张火车票
线程:9 抢到第1张火车票