ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)

ReentrantLock官方介紹

一個可重入的互斥鎖,具備synchronize提供的能力,並且比synchronize還有一定的擴展能力。

當一個重入鎖被一個線程成功持有後,只要該線程不主動釋放該鎖,那麼其他線程想要獲取該鎖,都會處於等待狀態。當一把重入鎖處於空閒沒有被任何線程持有時,只要有一個線程調用了lock方法,那麼該線程就成功持有該鎖了。

官方的這一段介紹,其想表達的意思總結概括為:該鎖具有互斥性

如果某個線程已經擁有了鎖,在釋放該鎖之前再次調用lock方法,也會立即返回成功,這是該鎖的第二個特性:可重入

ReentrantLock類的構造函數支持一個參數用來設置是否公平,這是該鎖的第三個特性:公平性


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)

構造函數


默認設置為非公平鎖。什麼是公平鎖,顧名思義,大家對持有該鎖是公平的,你一次我一次,我一次你一次,總之人人有份,先到先得,後到後得。來看下官方的專業介紹:

鎖傾向於等待時間更長的線程,等待時間最長的線程獲取到的鎖的概率最大;非公平鎖不能保證線程按特定的順序訪問;程序的很多個線程訪問公平鎖相比訪問非公平鎖吞吐量會更低一些,但是每個線程線程之間從等到到獲取到鎖的時間相差很小;需要注意一點:鎖的公平性不能保證線程調度的公平性,因此即便是多個線程爭搶一個公平鎖,也有可能同一個線程多次獲得鎖,使得其他線程還在等待。

這裡解釋一下最後一點:線程的執行取決於CPU的調度,這個調度不是線程自身能決定的,有可能同一個線程被CPU連續調度兩次,這個調度和這裡鎖的“公平性”是不發生關係的,也就說這個公平鎖其實是相對公平,而非絕對公平

OK,介紹到此,敲黑板劃重點了:

  1. ReentrantLock 具備互斥鎖能力
  2. ReentrantLock 可重入
  3. ReentrantLock 可滿足公平性

下面就這三點來從原理角度分析下。

在分析原理之前,先簡單看下ReentrantLock類的結構圖


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)

ReentrantLock類中的三個子類Sync、NonfairSync、FairSync,三個類的關係如下


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)


如何實現互斥

核心在於AbstractQueuedSynchronizer(併發同步器AQS),該類聲明瞭一個volatile的變量

<code>private volatile int state;/<code> 

該變量初始值為0,當一個線程成功持有鎖時,該線程會將該變量+1,當線程釋放鎖時會將該變量-1。變量的操作是通過CAS實現的。多個線程爭搶鎖時,會先判斷該變量是否為0,如果不為0,則獲取鎖失敗,反之,獲取鎖成功。這裡會出現線程並行的情況,即多個線程在同一時間將state由0變為1,但最終只會有一個線程操作成功。這裡有兩個核心點

  • volatile
  • cas

重入鎖的互斥性就是通過volatile和cas的特性實現的(高端的食材往往只需要最簡單的烹飪方式)


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)

至於volatile和cas的原理介紹,這裡就不贅述了。

如何實現重入

在實現互斥的基礎上增加重入,原理上也比較簡單,先上一張圖


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)


當同一個線程再次進行lock操作時,會將state變量繼續+1,也就是說同一個線程執行幾次加鎖,就必須執行幾次解鎖,否則會造成死鎖,死鎖的原因這裡就不贅述了,讀者可以想一想。

如何實現公平

公平是ReentrantLock的一大特性,下面看看如何實現公平。前面說到多個線程爭搶,只有一個線程能夠成功獲取到鎖,其他的線程都在等待,問題來了,都在哪裡等待?現實當中有很多類似的問題,我們去火車站窗口買票,只能有一個人佔用窗口,如果這個人走了,剩下的人都堆在一起憑藉蠻力爭搶,是做不到公平的,為了公平,就有了排隊制度,先到先來,後到後來。ReentrantLock也是通過“排隊思想”來解決公平問題的,其核心在於ReentrantLock的父類AbstractQueuedSynchronizer,該類內部維護了一個雙向鏈表,每當有獲取鎖失敗的線程出現時,就會被加入到這個雙向鏈表,等待這下一次獲取鎖,只有當自己是鏈表的頭結點時,才有機會成功獲取到鎖,這樣就實現了公平鎖。


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)

總結

ReentrantLock的互斥、重入、公平都是基於AQS實現的,本文沒有分析AQS的實現細節,只是從ReentrantLock的角度分析了原理性的幾個點。


ReentrantLock原理分析(高端的食材往往只需要最簡單的烹飪方式)


分享到:


相關文章: