ReentrantLock實現原理

ReentrantLock主要利用CAS+CLH隊列來實現。它支持公平鎖和非公平鎖,兩者的實現類似。

 

ReentrantLock的基本實現可以概括爲:先通過CAS嘗試獲取鎖。如果此時已經有線程佔據了鎖,那就加入CLH隊列並且被掛起。當鎖被釋放之後,排在CLH隊列隊首的線程會被喚醒,然後CAS再次嘗試獲取鎖。在這個時候,如果:

  • 非公平鎖:如果同時還有另一個線程進來嘗試獲取,那麼有可能會讓這個線程搶先獲取;
  • 公平鎖:如果同時還有另一個線程進來嘗試獲取,當它發現自己不是在隊首的話,就會排到隊尾,由隊首的線程獲取到鎖。

通過學習源碼的方式非常深刻的學習到了獨佔式鎖的獲取和釋放的過程以及同步隊列。可以做一下總結:

  1. 線程獲取鎖失敗,線程被封裝成Node進行入隊操作,核心方法在於addWaiter()和enq(),同時enq()完成對同步隊列的頭結點初始化工作以及CAS操作失敗的重試;
  2. 線程獲取鎖是一個自旋的過程,當且僅當 當前節點的前驅節點是頭結點並且成功獲得同步狀態時,節點出隊即該節點引用的線程獲得鎖,否則,當不滿足條件時就會調用LookSupport.park()方法使得線程阻塞
  3. 釋放鎖的時候會喚醒後繼節點;

總體來說:在獲取同步狀態時,AQS維護一個同步隊列,獲取同步狀態失敗的線程會加入到隊列中進行自旋;移除隊列(或停止自旋)的條件是前驅節點是頭結點並且成功獲得了同步狀態。在釋放同步狀態時,同步器會調用unparkSuccessor()方法喚醒後繼節點。

 

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