什么是虚假唤醒?
当一个条件满足时,唤醒了多个线程,其中部分线程不能被执行却执行了
比如操作一个变量:number初始是0,线程A对number进行+1,线程B对number进行-1,现在没有问题。但是,再有线程C对number进行+1和线程D对number进行-1时,就会出现不只是0和1的结果了。
明明加了锁,为什么还会产生负数情况?
是因为wait等待放在了if判断里面。
if判断只执行一次,然后就执行if()下边的了。而while会一直判断,直到满足条件才执行while()下边的代码
代码原因:
if (number != 0){
this.wait();//等待
}
解决办法时把2个地方的if换成while就可以了。
while (number != 0){
this.wait();//等待
}
下边是不会产生虚假唤醒的代码。(把while换成if就可以出现虚假唤醒)
/**
* 虚假唤醒
* 线程交替执行 操作同一个变量 num
*/
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CCC").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"DDDD").start();
}
}
//数字 资源类
class Data{
private int number = 0;
//执行 +1
public synchronized void increment() throws InterruptedException {
while (number != 0){
this.wait();//等待
}
number++;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,+1完毕
this.notifyAll();
}
//执行 -1
public synchronized void decrement() throws InterruptedException {
while (number==0){
this.wait();//等待
}
number--;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,-1完毕
this.notifyAll();
}
}