park/unpark 阻塞與喚醒線程


 

  使用 JAVA 進行多道編程時,除了通過 wait/notify 對線程進行阻塞/喚醒外,我們還可以使用 LockSupport 工具類來阻塞和喚醒線程。

  比如:

        Thread threadTest = new Thread(
                () -> {
                    System.out.println("thread start!");
                    LockSupport.park();
                    System.out.println("thread weakup!");
                }
        );
        threadTest.start();
        Thread.sleep(100);
        System.out.println(" from main thread");
        LockSupport.unpark(threadTest);

  執行結果:

   與 wait/notify 相比,park/unpark 方法更貼近操作系統層面的阻塞與喚醒線程。park/unpark 沒有基於對象鎖的上層判斷邏輯,更直接的通過系統調用來操作線程,當然在系統調用之上還是做了一些小封裝。與 wait/notify 相比:

  1. park不需要獲取某個對象的鎖
  2. 因為中斷的時候park不會拋出InterruptedException異常,所以需要在park之后自行判斷中斷狀態,然后做額外的處理。就像 sleep ,notify 喚醒后,jvm 會幫助我們檢查一次是否有 interrupt 信號,其原理之前做過解析 https://www.cnblogs.com/niuyourou/p/12392942.html ,將檢查 interrupt 信號的邏輯放在阻塞線程的邏輯之后,一旦被喚醒,首先執行檢查 interrupt 信號的邏輯,檢查完后退出 sleep/wait 方法,程序繼續向下執行。而 park / unpark 並沒有提供類似的機制,如果需要我們應自己在 park 方法后加入檢查 interrupt 信號的邏輯。
  3. 想想happen-before原則中有一條,同一個鎖的unlock操作happen-before此鎖的lock操作。park/unpark 並沒有涉及到鎖操作,但我們確實有保證在一對操作中, park 發生在 unpark 之前的需求,否則可能會造成程序的死鎖。關於這點 park/unpark 通過為線程附加狀態位滿足了我們的需求:unpark調用時,如果當前線程還未進入park,則將許可設置為true;park調用時,判斷許可是否為true,如果是true,則 park 不阻塞線程,程序繼續往下執行;如果是false,則阻塞線程。所以只要我們的 park/unpark 成對出現,無論執行順序如何,都不會因此造成死鎖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM