package com.han.demo01;
public class TestPC {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}
class Data {
private int num = 0;
public synchronized void increment() throws InterruptedException {
if (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "==>" + num);
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
if (num == 0) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "==>" + num);
this.notifyAll();
}
}
结果: 由于
if (num != 0) {
this.wait();
}
和
if (num == 0) {
this.wait();
}
中采用的都是if判断,后面 this.notifyAll()会导致虚假唤醒。 比如生产者A添加结束后,本意是唤醒消费者线程,但是由于生产者C在它的上一个时间片通过if的仅一次判断之后就一直在等待,而此时被生产者A唤醒了,就会直接进行添加。是的数值变得很大。反之,消费者被虚假唤醒会导致数值变的很小
虚假唤醒:https://blog.csdn.net/weixin_45668482/article/details/117373700
那么这里需要将if判断改为while判断即可防止虚假唤醒。
package com.han.demo01;
public class TestPC {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}
class Data {
private int num = 0;
public synchronized void increment() throws InterruptedException {
while (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "==>" + num);
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
while (num == 0) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "==>" + num);
this.notifyAll();
}
}
结果:
|