1. 程式人生 > >J.U.C重入鎖

J.U.C重入鎖

itl 數據 cnblogs 執行 ont 微軟 nds asq jpg

ReentrantLock重入鎖

技術分享

ReentrantLockJava並發包中互斥鎖,它有公平鎖和非公平鎖兩種實現方式, 重入的意思就是,如果已經獲得了鎖,如果執行期間還需要獲得這個鎖的話,會直接獲得所,不會被阻塞,獲得鎖的次數加1;每執行一次unlock,持有鎖的次數減1,當為0時釋放鎖。這點,Synchronized 具有同樣語義。

技術分享

技術分享

技術分享

SyncReentrantLock中有兩種子類:非公平鎖NonfairSync、公平鎖FairSync,默認情況下為非公平鎖。

技術分享

先判斷鎖的狀態,通過CAS來搶占,搶占成功,直接返回true

技術分享

如果鎖的持有者線程為當前線程(偏向鎖)的話,則通過累加狀態標識重入次數,因為沒有競爭,所以通過setStatus修改。否則返回false,入隊等待獲取鎖。

技術分享

當前線程釋放,releases表示釋放次數(重入)。如果為0獨占線程設為null。最後更新狀態

技術分享

lock()方法

非公平鎖NonfairSync

技術分享 線程進入先搶占鎖,通過CAS操作compareAndSetState(0, 1)方法。0表示尚未有線程持有該鎖;>=1則表示存在線程持有該鎖,並重入對應次數。參考AbstractQueuedSynchronizer類。

技術分享

公平鎖FairSync

技術分享

技術分享

getState==0沒有線程持有該鎖,並且通過

!hasQueuedPredecessors()判斷當前等待隊列沒有前繼線程(也就是說,沒有比我優先級更高的線程在請求鎖了)獲取鎖的情況下,通過CAS搶占鎖,並設置自己為鎖的當前擁有者,技術分享 線程重入通過累加狀態位標記重入次數。

ReentrantReadWriteLock

支持與 ReentrantLock 類似語義的 ReadWriteLock 實現。

例子一:讀寫一個共享數據的操作

技術分享

例子二:讀寫集合的操作,用於讀多寫少的情況。

技術分享

技術分享

技術分享

測試例子二:三分之一線程寫任務,其余模擬隨機讀任務key1-3保證讀不為空。

技術分享

J.U.C重入鎖