關於LockSupport


concurrent包的基礎

Doug Lea 的神作concurrent包是基於AQS (AbstractQueuedSynchronizer)框架,AQS框架借助於兩個類:Unsafe(提供CAS操作)和LockSupport(提供park/unpark操作)。因此,LockSupport可謂構建concurrent包的基礎之一。理解concurrent包,就從這里開始。

兩個重點

  • 操作對象

歸根結底,LockSupport調用的Unsafe中的native代碼: 

public native void unpark(Thread jthread); 
public native void park(boolean isAbsolute, long time); 

兩個函數聲明清楚地說明了操作對象:park函數是將當前Thread阻塞,而unpark函數則是將另一個Thread喚醒。

與Object類的wait/notify機制相比,park/unpark有兩個優點:1. 以thread為操作對象更符合阻塞線程的直觀定義;2. 操作更精准,可以准確地喚醒某一個線程(notify隨機喚醒一個線程,notifyAll喚醒所有等待的線程),增加了靈活性。

  • 關於許可

在上面的文字中,我使用了阻塞和喚醒,是為了和wait/notify做對比。其實park/unpark的設計原理核心是“許可”。park是等待一個許可。unpark是為某線程提供一個許可。如果某線程A調用park,那么除非另外一個線程調用unpark(A)給A一個許可,否則線程A將阻塞在park操作上。

有一點比較難理解的,是unpark操作可以再park操作之前。也就是說,先提供許可。當某線程調用park時,已經有許可了,它就消費這個許可,然后可以繼續運行。這其實是必須的。考慮最簡單的生產者(Producer)消費者(Consumer)模型:Consumer需要消費一個資源,於是調用park操作等待;Producer則生產資源,然后調用unpark給予Consumer使用的許可。非常有可能的一種情況是,Producer先生產,這時候Consumer可能還沒有構造好(比如線程還沒啟動,或者還沒切換到該線程)。那么等Consumer准備好要消費時,顯然這時候資源已經生產好了,可以直接用,那么park操作當然可以直接運行下去。如果沒有這個語義,那將非常難以操作。

  • 其它細節 
    理解了以上兩點,我覺得應該把握了關鍵,其它細節就不是那么關鍵,也容易理解了,不作分析。

 


免責聲明!

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



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