转载:https://www.cnblogs.com/dk1024/p/14163377.html
1、什么是虚假唤醒?
虚假唤醒就是在多线程执行过程中,线程间的通信未按照我们幻想的顺序唤醒,故出现数据不一致等不符合我们预期的结果。比如 我的想法是:加1和减1交替执行,他却出现了2甚至3这种数:请看下面例子:
假设有四个线程A、B、C、D同时启动,我们定义A和B为加法线程,C和D为减法线程,每个线程执行5次回到原点,我们的期望结果是:0,1,0,1,0,1…0,1,0
顺此进行,但执行结果却是:
public class ThreadTest {
public static void main(String[] args) {
Data data = new Data();
//生产者线程A
new Thread(() -> {
for (int i = 0;i < 5;i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
//生产者线程B
new Thread(() -> {
for (int i = 0;i < 5;i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
//消费者线程C
new Thread(() -> {
for (int i = 0;i < 5;i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
//消费者线程D
new Thread(() -> {
for (int i = 0;i < 5;i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
//数据类
static class Data {
//表示数据个数
private int number = 0;
public synchronized void increment() throws InterruptedException {
if (number != 0) {
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName() + "生产了数据:" + number);
this.notify();
}
public synchronized void decrement() throws InterruptedException {
if (number == 0) {
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName() + "消费了数据:" + number);
this.notify();
}
}
}