传统生产者消费者问题、防止虚假唤醒
package JUC;
/**
* Copyright © 2021 eSunny Info. Tech Ltd. All rights reserved.
*
* 功能描述:生产者
* 操作同一个变量 通知等待唤醒
* Provider num + 1
* Consumer num - 1
*/
public class ProviderConsumer {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A") .start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B") .start();
}
}
class Data{//数字 资源类
private int number = 0;
// +1
public synchronized void increment() throws InterruptedException {
if (number!=0) {
//等待减少
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName() + "票数加 +"+ number);
//通知
this.notifyAll();
}
// -1
public synchronized void decrement() throws InterruptedException {
if (number==0) {
//等待增加
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName() + "票数减 -"+ number);
//通知
this.notifyAll();
}
}
2个线程看起来没有问题,但是当打开4个线程呢?
防止虚假唤醒
线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。虽然实践中很少发生,但应用程序必须通过测试应该使线程被唤醒的条件来防范,并且如果条件不满足则继续等待。换句话讲,等待应该总是出现在循环中:
将if 修改成while循环判断