ReentrantLock代碼邏輯

Lock方法執行調用直接獲取鎖(非公平鎖沒有該步驟),獲取不到執行sync.lock();由於公平參數決定創建的是FailLock是NonFailSync.這個時候就會調用具體實現的lock(Sync中是抽象)方法. 調用acquire(1)方法(Sync中抽象方法) 該方法中調用AQS中的tryAcquire方法(抽象方法),最終調用實現類的tryAcquire方法.
鎖獲取邏輯:
1.判讀是否是head的後繼節點(head中不存在Thread).如果是則嘗試獲取鎖.成功退出否則進行第2步(非公平鎖沒有後繼節點的判斷)
2.調用addWaiter進行入隊操作.根據Thread創建一個Node,Cas嘗試入隊,失敗後調用snq方法(該方法返回該節點的前一個節點,在ReentrantLock中沒有使用該返回值)進行自旋入隊.
3. 返回入隊後的Node再次判斷是否是head的後繼節點,是則嘗試加鎖,不是或嘗試加鎖失敗.進行4阻塞判斷
4.
(1)如果前一個節點是正常的節點(SINGAL),返回true進行否則進行(2) (2)判斷前繼節點是否是取消狀態,如果是,循環刪除取消狀態的節點,並將prev指向上上個節點.直至前繼節點是有效的節點(目的是增加後繼遍歷的性能) 如果不是,嘗試讓自己成爲當前鎖的競爭者(只有一個). 返回false 結束
5.調用Unsafe park方法進行阻塞 鎖解除邏輯: 1.嘗試釋放鎖,如果當前線程不是鎖的owner報monitor異常.否則進行第2步 2.判斷是否鎖已經釋放完成(可重入鎖,加了幾次就要釋放幾次),否返回.是則進行第3步 3.釋放head的後續節點(unsafe unpark方法),
(1)如果後續節點是不是取消狀態的節點,喚醒
(2)否則則從尾部向前遍歷最前面的狀態小於0的節點並喚醒——爲什麼有這部分 因爲如果獲取鎖的過程異常,lock方法finnal語句塊中將執行canncelAcquire操作.將改節點從隊列中摘除.摘除是後繼node指向自身,前繼node的後繼node指向下一個正常狀態的node.沒有動自己的前繼node指向,所以從後向前遍歷是可以保證順序的.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章