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间隔执行,可是多执行几回就有可能会出现如下情形java
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(); }