多執行緒交叉列印數字,執行緒切換,結果通知思想
阿新 • • 發佈:2018-12-14
一道面試題,兩個執行緒交叉列印奇偶數。
這裡會運用synchronized鎖機制,wait和notifyAll方法,當然也可以使用ReentrantLock,本質鎖競爭
僅線上程需要的時候持有鎖,其餘時間檢查自身執行緒鎖,釋放執行緒自己持有的鎖。
public class Test2 { public static void main(String[] args) { Num num = new Num(); //執行緒1-奇數執行緒 new Thread(() -> { while (num.number < 100){ synchronized (num){ //奇數 if (num.number%2 == 1){ System.out.println(Thread.currentThread().getName() + "\t奇數執行緒:" + num.number); num.number++; num.notifyAll(); } else { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); //執行緒2-偶數執行緒 new Thread(() -> { while (num.number < 100){ synchronized (num){ //奇數 if (num.number%2 == 1){ try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println(Thread.currentThread().getName() + "\t偶數執行緒:" + num.number); num.number++; num.notifyAll(); } } } }).start(); } static class Num { public int number = 1; } }
程式碼很簡單,通過wait和notifyAll方法來釋放自身執行緒鎖和讓其他執行緒持有鎖。
這裡要注意:使用synchronized加鎖必須是物件,synchronized就是通過物件頭的方式加鎖的。
這裡的思想在RPC框架中非常常用。
1. 發起RPC的呼叫的時候,程式不會立馬返回,需要將自身執行緒等待
2. 呼叫結果返回時,需要喚醒自身執行緒。
3. 通知機制,這裡使用notifyAll通知,而RPC一般使用觀察者模式,回撥通知。