ReenterLock內部是怎麼實現的

2021-09-01 09:27:33 字數 2436 閱讀 9810

reentrantlock內部有公平鎖和非公平鎖兩種,而這兩種鎖都是基於aqs同步器實現的。aqs同步器太難看懂,先簡單看下reentrantlock的原始碼,再反推回去看aqs。

1、公平鎖能保證:老的執行緒排隊使用鎖,新執行緒仍然排隊使用鎖。

2、非公平鎖保證:老的執行緒排隊使用鎖;但是無法保證新執行緒搶占已經在排隊的執行緒的鎖。

在公平鎖中,每一次的tryacquire都會檢查clh佇列中是否仍有前驅的元素,如果仍然有那麼繼續等待,通過這種方式來保證先來先服務的原則。

而非公平鎖,首先是檢查並設定鎖的狀態,這種方式會出現即使佇列中有等待的執行緒,但是新的執行緒仍然會與排隊執行緒中的對頭執行緒競爭(但是排隊的執行緒是先來先服務的),所以新的執行緒可能會搶占已經在排隊的執行緒的鎖,這樣就無法保證先來先服務,但是已經等待的執行緒們是仍然保證先來先服務。

預設建構函式:

預設就是使用的非公平鎖(估計是因為非公平鎖效率高吧)。

非公平鎖加鎖:lock()

首先使用cas的方式將state設定為1,1

代表當前

執行緒獲取了一次

鎖,並將當前執行緒設定為獨佔。也就是說reentrantlock

內部的非公平鎖是乙個獨佔鎖。(其實從下面的tryacquire()就可以看出來它是乙個獨佔鎖,aqs同步器獨佔鎖搶占的命名就是這個)

如果狀態設定未成功,則呼叫aqs類中的acquire(1)進行鎖的強佔(aqs中詳細的怎麼執行的後續文章分析吧)。acquire(1)會首先執行自定義的鎖強佔邏輯,不成功則執行由它定義的後續邏輯。記得

內部會設定

將強佔的執行緒放到佇列裡面,這不就違反了公平的邏輯麼?

而且放到隊裡

裡面的話鎖會自旋,有沒有不自旋的方法

?看下它自定義的鎖搶占方法:nonfairtryacquire(int acquires)

我將它分成了上下兩部分:

如果當前的state=0,表示鎖被釋放了,那麼仍然通過cas的方式將自己設定進去。

如果還是當前執行緒來強佔鎖,那麼將

state+1

,這就是重入的邏輯

,側面也說明了aqs

類沒有實現

重入邏輯。

釋放鎖:unlock(),只有乙個方法,看來公平鎖和非公平鎖釋放的邏輯是一致的

呼叫的是aqs類中的釋放

獨佔鎖的邏輯,我們稍微看下aqs裡面怎麼實現的:

其實就是呼叫使用者自身定義的tryrelease()邏輯,然後再做一些收尾工作。那麼久看下自定義的釋放鎖的方法。

其實核心就這句話,lock幾次就要unlock幾次,執行緒不在占有鎖就是state減到0的時候。看到

這裡還不明白的一點是非公平怎麼實現的

,這個要看

aqs了。

建構函式傳入true:

看下它加鎖的邏輯:lock()

和非公平鎖是一樣的,底層呼叫的還是aqs的邏輯,只是自定義的加鎖的方式不一樣,並且它也是實現的獨佔鎖的介面,那就是說reentrantlock中的

鎖都是獨佔鎖。

和非公平鎖唯一不同的是,它也有

queue的概念,

搶占的執行緒是放入到佇列中,每次從佇列的頭部獲取執行緒,

讓這個執行緒來

獲取鎖。至於重入的概念和非公平鎖是一致。

reentrantlock類中還有乙個newcondition()方法,但是這個好像不是給它自己本身用的,而是給

它物件用的:

可以參考我分析cyclicbarrier那篇文章,這個類中cyclicbarrier類中就是用來判斷一組物件是不是達到了某種條件,額…後面看的越多估計會理解的越深一點。

SpringMVC處理請求的大致流程是怎麼樣的

spring mvc請求處理架構圖 1 使用者首先傳送請求到前端控制器dispatcher servlet 3 接著將得到的處理器handlerexecutionchain包裝成為handleradapter 介面卡 4 根據得到的handleradapter呼叫真正的處理器得到modelandvi...

Android View類中的生命週期是怎樣的

android view有以下14個週期 1 onfinishinflate 當view中所有的子控制項均被對映成xml後觸發 2 onmeasure int int 確定所有子元素的大小 3 onlayout boolean int int int int 當view分配所有的子元素的大小和位置時...

生成器python python生成器是怎樣工作的

第一部分 在掌握python生成器之前,你需要理解普通的python函式是如何工作的。通常,當乙個python函式呼叫乙個子程式時,子程式保留控制權直到它返回,或者丟擲乙個異常。然後控制權被交還給呼叫者 父程式 def foo bar def bar pass python的標準直譯器是由c寫成的。...