AQS鎖機制原理

2021-06-22 01:04:13 字數 1745 閱讀 9011

reentrantreadwritelock 與

reentrantlock 核心就是

sync(aqs子類)及aqs

,synchronized基於

內部物件鎖

jvm指令的級別

reentrantreadwritelock 引用傳入 內部類 readlock和writelock,將其sync傳入兩個內部類,如果讀鎖如果發現沒有排他鎖

exclusivecount

則可以上鎖  

reentrantlock 機制原理:

reentrantlock就是基於sync的,而sync就是一種aqs子類,其中核心機制aqs都實現

sync及aqs的核心實現(原始碼級別)

aqs核心思想是,如果被請求的共享資源空閒,則將當前請求資源的執行緒設定為有效的工作執行緒,並且將共享資源的設定為鎖定狀態。如果被請求的共享資源被占用,那麼就需要一套執行緒阻塞等待以及被喚醒時鎖分配的機制,這個機制aqs是用clh佇列鎖實現的,即將暫時獲取不到鎖的執行緒加入到佇列中。

那麼首先看一下clh佇列鎖的資料結構及實現演算法。

(a)clh佇列的資料結構(如圖):

簡述:clh佇列是乙個虛擬的雙向佇列(虛擬的雙向佇列即不存在佇列例項,僅存在結點之間的關聯關係)。aqs是將每條請求共享資源的執行緒封裝成乙個clh鎖佇列的乙個結點(node)來實現鎖的分配的。具體構建佇列的演算法是這樣的:

假設: 有共享資源s目前正被l3執行緒占用,此時有l1、l2執行緒分別對資源s進行lock操作以及獲取鎖後進行unlock操作。具體的流程如下:

(1)由於目前資源s被占用,所以將執行緒l1包裝成乙個clh佇列的node,將這個node的前驅(prev)指向當前對列裡的隊尾,放入隊尾這個操作採用了cas原語(原子操作)。如果當前的隊尾為null,那麼就建乙個虛擬的header,然後將t1執行緒掛載到虛擬header下。核心**如下:

ps:  addwaiter就是放入佇列的操作。

ps:採用cas將節點加入到隊尾,如果隊尾為null進入enq操作。

ps:建立了乙個虛擬的header

(2) l2執行緒請求資源s,那麼它和l1執行緒一樣將自己加入到隊尾,l2的prev指向l1,l1.next指向l2(雙向佇列嘛)。

(3) 當l3釋放資源即unlock的時候,喚醒與l3關聯的下乙個節點,同時釋放當前節點。關鍵**:

(b)每個結點類的屬性及方法資訊:

屬性簡述:cancelled:表示因為超時或者中斷,結點被設定為取消狀態,被取消的狀態結點不應該去競爭鎖。signal:表示這個結點的繼任結點被阻塞了,因為等待某個條件而被阻塞。condition:表示這個結點在佇列中,因為等待某個條件而被阻塞。這幾個是常量屬性預設值為:

這幾個常量用來設定waitstatus屬性。

thread屬性表示關聯到這個結點的執行緒。prev和next就是關聯前後結點的索引變數。nextwaiter 記錄的是這個結點是獨佔式還是可共享的屬性。

reentrantlock當中的部分例項**:

1.     兩個建構函式(可見預設使用的非公平鎖的分配機制):

2.     lock方法的實現其實就是直接**了sync lock的實現:

3.     trylock方法也是一樣的,都是**自sync

4.     解鎖方法

AQS共享鎖的實現原理

前面的文章lock的實現中分析了aqs獨佔鎖的實現原理,那麼接下來就分析下aqs是如何實現共享鎖的。共享鎖的介紹 共享鎖 同一時刻有多個執行緒能夠獲取到同步狀態。那麼它是如何做到讓多個執行緒獲取到同步狀態呢?來看一下獲取共享鎖的過程 1.執行緒呼叫aqs的acquireshared 申請獲取鎖 可有...

AQS共享鎖應用之Semaphore原理

我們呼叫semaphore方法時,其實是在間接呼叫其內部類或aqs方法執行的。semaphore類結構與reetrantlock類相似,內部類sync繼承自aqs,然後其子類fairsync和nofairsync分別實現公平鎖和非公平鎖的獲取鎖方法tryacquireshared int arg 而...

JDK鎖的基礎 AQS實現原理(二)

上文介紹了aqs的一些基礎知識,包括clh鎖的原理和aqs的一些資料結構,這篇文章中我們來分析一下aqs的方法。aqs是乙個抽象類,定義了幾個模板方法交給子類去實現,分別是 protected boolean tryacquire int arg protected boolean tryrelea...