【Java多线程】多线程虚假唤醒
public class CustomerDemo {
public static void main(String[] args) {
/**
* 要求一个线程增加,一个线程减少
*/
Number number= new Number();
new Thread(() -> {
for (int i = 0; i < 10 ;i ++) {
try {
number.decrease();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10 ;i ++) {
try {
number.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10 ;i ++) {
try {
number.decrease();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 10 ;i ++) {
try {
number.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}
/**
* 线程之间的通信
*/
class Number {
private int num = 0;
public synchronized void decrease() throws InterruptedException {
if (num == 0) {
this.wait();
}
num --;
System.out.println(Thread.currentThread().getName() + " ... " + num);
this.notifyAll();
}
public synchronized void increase() throws InterruptedException {
if (num != 0) {
this.wait();
}
num ++;
System.out.println(Thread.currentThread().getName() + " ... " + num);
this.notifyAll();
}
}
上面程序最理想的状态是0 ,1,0,1间隔执行,但是多执行几次就有可能会出现以下情形
B ... 1
A ... 0
B ... 1
.....
.....
A ... -1
A ... -2
A ... -3
A ... -4
这是因为多线程的虚假唤醒导致的,在多线程中判断必须使用while
如果使用if
if (num != 0) {
// 假设此时有B,D线程在这里wait,如果被唤醒后,不会再次进行num != 0判断,这样就会导致num ++ 两次。如果使用while的话,线程被唤醒以后会再次进行条件判断
this.wait();
}