1. 程式人生 > >多執行緒交叉列印數字,執行緒切換,結果通知思想

多執行緒交叉列印數字,執行緒切換,結果通知思想

一道面試題,兩個執行緒交叉列印奇偶數。

這裡會運用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一般使用觀察者模式,回撥通知。