從ReentrantLock加鎖解鎖角度分析AQS

2022-01-29 18:57:35 字數 2591 閱讀 3611

本文用於記錄在學習aqs時,以reentrantlock為切入點,深入原始碼分析reentrantlock的加鎖和解鎖過程。

同步器aqs的主要使用方式是繼承,子類通過繼承同步器並實現它的抽象方法來管理同步狀態(通常鎖或者同步元件內部會實現乙個sync類(該類是乙個靜態內部類),然後讓sync類去繼承aqs類,通過繼承aqs佇列同步器並實現它的抽象方法來管理同步狀態),對同步狀態進行更改需要使用同步器提供的3個方法getstatesetstatecompareandsetstate,它們保證狀態改變是安全的。

下圖是reentrantlock中所有的內部類和方法:

3個內部類之間的關係如下圖所示:

以reentrantlock為例,從原始碼分析如何進行加鎖和解鎖。

reentrantlock lc = new reentrantlock();

lc.lock();

lc.unlock();

(1)reentrantlock建構函式(為了方便分析,我們以非公平隊列為例子)

reentrantlock類中的lock()方法呼叫sync例項中的lock()方法,因為我們是以非公平隊列為例子,所以此時的sync例項的型別為nonfairsync。即呼叫nonfairsync.lock()

緊接著進入209行對應的acquire(1)方法:該方法位於aqs框架中,且被final修飾,即不能被子類重寫。

緊接著進入tryacquire(int arg)方法

我們發現aqs中的tryacquire(int arg)方法中沒有實現體,說明tryacquire(int arg)方法需要aqs子類實現,根據上面的繼承圖可知,sync以及nonfairsync都是aqs的子類,由下圖可知,tryacquire(int arg)方法的實現位於nonfairsync內部類中

進入nonfairsync內部類中的ryacquire(int arg)方法可以發現其呼叫了sync靜態內部類中的nonfairtryacquire方法。

至此成功獲取了鎖。

(1) 通過reentrantlock的加鎖方法lock進行加鎖操作。

(2) 會呼叫到內部類sync的lock方法,根據reentrantlock初始化選擇的公平鎖和非公平鎖,執行相關內部類的lock方法,本質上都會執行aqs的acquire方法。

(3) aqs的acquire方法會執行tryacquire方法,但是由於tryacquire需要自定義同步器實現,因此執行了reentrantlock中的tryacquire方法,由於reentrantlock是通過公平鎖和非公平鎖內部類實現的tryacquire方法,因此會根據鎖型別不同,執行不同的tryacquire。

(4) tryacquire是獲取鎖邏輯,獲取失敗後,會執行框架aqs的後續邏輯,跟reentrantlock自定義同步器無關。

(3)lc.unlock()

釋放鎖的過程和加鎖過程類似,不走進原始碼,直接上文本版流程

(1) 通過reentrantlock的解鎖方法unlock進行解鎖。

(2) unlock會呼叫內部類sync的release方法,該方法繼承於aqs。

(3) release中會呼叫tryrelease方法,tryrelease需要自定義同步器實現,tryrelease只在reentrantlock中的sync實現,因此可以看出,釋放鎖的過程,並不區分是否為公平鎖。

(4) 釋放成功後,所有處理由aqs框架完成,與自定義同步器無關。

經過上述的學習,可以歸納總結出如果要自定義乙個同步元件,可以按照如下步驟

ReentrantLock實現同步

reentrantlock 也可以實現synchronized方法 塊的同步效果。reentrantlock 實現同步 如下 1 新建乙個service類 public class myservice public static void methodb 2 新建乙個測試類 public class...

ReentrantLock之unlock方法分析

public void unlock public final boolean release int arg return false release 1 嘗試在當前鎖的鎖定計數 state 值上減1。成功返回true,否則返回false。當然在release 方法中不僅僅只是將state 1這麼...

ReentrantLock 原理分析

public void lock 這是lock的原始碼,呼叫的其實是sync這個物件的lock函式,而sync是reentrantlock內部類sync的乙個物件例項,他有兩種實現nonfairsync 非公平鎖 和fairsync 公平鎖 先看公平鎖的lock函式 final void lock ...