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(); }