java ReentrantLock鎖實現原理

ReentrantLock原理:通過CAS指令 + AQS隊列實現對線程加鎖。

結構:ReentrantLock實現接口Lock的lock()和unLock()方法,內部有兩個內部類公平鎖FairSync和非公平鎖NonfairSync,這兩個類均繼承了AbstractQueueSynchronizer(裏面存有Node雙向鏈表組成一個隊列,還有head,tail節點,state狀態,waitStatus狀態)

一、非公平鎖加鎖過程:

    1、當線程調用lock方法獲取鎖,通過cas的方式去設置state狀態獲取鎖,如果獲取成功則將exclusiveOwnerThread變量設置爲當前線程。並返回true。業務正常執行。

    2、當第一次獲取鎖失敗後,判斷state是否爲0,如果不爲0,則判斷當前線程是否與exclusiveOwnerThread線程一樣(可重入性),相當則state加1,返回true。 如果state==0,則繼續嘗試獲取鎖,若獲取成功,則設置變量並返回true

       若返回爲false,則進入如下面第三步。

  3、創建一個node節點並進行入隊列:pre指向tail節點,tail節點的next執行新節點。

  4、隊列中節點的waitStatus狀態進行設置:如果新節點的pre節點waitStatus狀態是singnal(-1),則通過LockSupprt.park方法阻塞當前線程。(內部是調用unsafe的方法對線程),如果新節點的pre節點是大於0,說明這些節點已經廢棄,可以跳過,直接繼續找前面的節點,直到找到節點狀態小於0的,然後設置爲signal,並設置爲新節點的pre。然後阻塞當前線程。

5、當調用unlock時,會對state變量減1(考慮重入情況),當state==0時,再設置exclusiveOwnerThread==null。然後對隊列頭節點線程喚醒。通過LockSupport.unpark方式。

二、公平鎖的加鎖過程:

1、線程調用lock方法時,不會去嘗試獲取鎖,判斷state是否爲0,如果不爲0,則判斷當前線程是否與exclusiveOwnerThread線程一樣(可重入性),一樣則返回true,如果state==0, 且隊列是空的,則會嘗試獲取鎖。獲取成功,則返回true,執行業務。

   如果獲取鎖失敗或隊列不是空。則創建一個新節點node,然後如隊列。與非公平鎖流程類似。

參考一些優秀解析:
https://www.cnblogs.com/waterystone/p/4920797.html

https://blog.csdn.net/fuyuwei2015/article/details/83719444

 

 

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