1. 程式人生 > 實用技巧 >Java 可重入鎖的概念

Java 可重入鎖的概念

看了個視訊講可重入鎖,但是總是沒講清楚,自己寫程式碼試了一下,貼上來記錄好理解。

可重入鎖的概念

視訊中說執行緒A呼叫帶鎖的function1()時,如果function1()又呼叫了另一個帶鎖的function2(),那麼就自動獲取到了function2()的鎖,但是這樣理解很繞,我自己理解是:當一個執行緒獲取到了一個鎖lock時,相當於是佔有了所有由這個lock所鎖定的部分(即使這部分處於不同的方法或不同的synchronized塊中。

程式碼示例


public class MyReenterLockStudy {
    public static void main(String[] args) throws InterruptedException {
        MyReenterLockStudy stu = new MyReenterLockStudy();
        new Thread(stu::function1,"執行緒 1").start();
        new Thread(stu::function2,"執行緒 2").start();
        Thread.sleep(2000);
    }
    private synchronized void function1()  {
        System.out.println(Thread.currentThread().getName()+"執行\t 進入function1");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        function2();
    }

    private void function2() {
        System.out.println(Thread.currentThread().getName()+"執行\t 進入function2");
        synchronized (this){
            System.out.println(Thread.currentThread().getName()+"執行\t function2同步體");
        }
    }
}

執行結果:


示例解釋

執行可能會出現 3 種情況,我們分情況來分析。

第一種

執行緒1 首先開始執行,呼叫function1(),拿到鎖,並輸出 執行緒 1執行 進入function1,然後休眠1秒,此時也還持有著function2()的synchronized塊內的鎖;
執行緒2 執行呼叫function2(),可以執行function2()中無鎖的部分(執行緒 2執行 進入function2),然後由於鎖被執行緒1佔有,只能等待執行緒1執行完再執行synchronized的部分。

第二種

此種和方法一類似,只是執行緒2先運行了,但仍然是由執行緒1先搶到了鎖(雖然執行緒1拿到的是function1()那裡的鎖,但這仍然阻止了執行緒2去執行function2()的後續部分)。

第三種

此種下,執行緒2先執行輸出並搶到了位於function2()中synchronized塊的鎖,執行緒1就無法拿到function1()的鎖,無法執行,只能等執行緒2結束。