引言
当多个线程操作共享的数据时,共同修改该数据。可能出现,当第1个线程想操作A状态的数据时,发现已经被第二个线程修改为了B状态,于是无法完成本想完成的任务。即:存在两个或者两个以上的线程对象共享同一个资源。
也存在操作共享资源线程代码有多条导致多线程安全出现问题。
解决
1、利用同步代码块
public class Ticket implements Runnable{
private int number = 100;
//在成员位置定义锁对象
private Object lock = new Object();
@Override
public void run() {
//车站不停地在卖票
while(true){
//将一个完整动作使用synchronized同步代码块包裹
synchronized(lock) //锁对象自行设置,同一即可{
//线程暂停20毫秒
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
//有票就买票
if(number>0){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+"正在销售第"+(number)+"张票");
number--;
}else{
//没有票,就跳出循环,不再卖票
break;
}
}
}
}
}
2、利用同步方法
2.1动态同步
//调用即可同步运行
public synchronized void sell(){
//线程暂停20毫秒
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
//有票就买票
if(number>0){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+"正在销售第"+(number)+"张票");
number--;
}
}
2.2静态同步
//该锁的对象为 类.class (共享使用一定注意,否则锁不住)
public static synchronized void sell(){
//线程暂停20毫秒
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
//有票就买票
if(number>0){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+"正在销售第"+(number)+"张票");
number--;
}
}