JAVA多線程之park & unpack


一、park & unpack demo

main-start 時間Thu May 13 16:17:32 CST 2021
Thread-0
main-end 時間Thu May 13 16:17:33 CST 2021

特點:該方式實現線程的通信不需要鎖,並且可以喚醒指定的線程

Object.wait()、Object.notify() :

  • wait和notify都是Object中的方法,在調用這兩個方法前必須先獲得鎖對象,這限制了其使用場合:只能在同步代碼塊中。
  • 當對象的等待隊列中有多個線程時,notify只能隨機選擇一個線程喚醒,無法喚醒指定的線程。

二、LockSupport阻塞和喚醒線程原理

LockSupport是通過控制變量_counter來對線程阻塞喚醒進行控制的。原理有點類似於信號量機制。但是_counter的值只有0或者1

當調用park()方法時,會將_counter置為0,同時判斷前值,等於0說明前面被park過,則直接進入排隊,否則將使該線程阻塞。
當調用unpark()方法時,會將_counter置為1,同時判斷前值,小於1會進行線程喚醒,否則直接退出。
形象的理解,線程阻塞需要消耗憑證(permit),這個憑證最多只有1個。當調用park方法時,如果有憑證,則會直接消耗掉這個憑證然后正常退出;但是如果沒有憑證,就必須阻塞等待憑證可用;而unpark則相反,它會增加一個憑證,但憑證最多只能有1個。
為什么可以先喚醒線程后阻塞線程?
因為unpark獲得了一個憑證,之后調用park因為有憑證消費,故不會阻塞。
為什么喚醒兩次后阻塞兩次會阻塞線程。
因為憑證的數量最多為1,連續調用兩次unpark和調用一次unpark效果一樣,只會增加一個憑證;而調用兩次park卻需要消費兩個憑證,但我們有且只有一個憑證。

 


免責聲明!

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



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