欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解Redisson分布式鎖底層實(shí)現(xiàn)原理

 更新時(shí)間:2023年07月12日 09:29:08   作者:_Apricity  
這篇文章主要詳細(xì)介紹了Redisson分布式鎖底層實(shí)現(xiàn)原理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

在Java中有很多保證線程安全的方式,比如synchorized,lock鎖等等,這些在單機(jī)環(huán)境下都能發(fā)揮不錯(cuò)的作用,但是在分布式的環(huán)境下,這些機(jī)制就會(huì)失去大部分的作用。

在分布式環(huán)境下就需要引入分布式鎖,實(shí)現(xiàn)分布式鎖的方式有好多種,比如redis、zookeeper,或者通過(guò)數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn),但是在分布式的情況下還需要考慮機(jī)器宕機(jī)的情況,如果某臺(tái)機(jī)器上的線程獲取到了這個(gè)鎖,但此時(shí)機(jī)器宕機(jī)了。那么就沒辦法去釋放,就會(huì)造成死鎖的情況。

為了避免這種情況,就需要給鎖加上一個(gè)過(guò)期時(shí)間,而過(guò)期時(shí)間的設(shè)定又是一個(gè)令人非常頭疼的問(wèn)題。

在Redisson種有一個(gè)看門狗機(jī)制,它給出了一種過(guò)期時(shí)間的很好的解決辦法。下面就來(lái)研究一下它具體實(shí)現(xiàn)吧。

Redisson的加鎖入口是tryLock(),此方法需提供獲取鎖的等待時(shí)間,如果在規(guī)定時(shí)間內(nèi)未搶到鎖,會(huì)返回false。

這里可以看到tryLock()方法實(shí)際上是調(diào)用了下面這個(gè)方法,這里給了一個(gè)leaseTime的默認(rèn)值,至于為什么是-1,我們接著往下看。

進(jìn)來(lái)之后會(huì)發(fā)現(xiàn),這個(gè)方法的核心就是執(zhí)行一個(gè)tryAcquire方法,我們點(diǎn)進(jìn)去看一下。

tryAcquire方法實(shí)際會(huì)去執(zhí)行tryAcquireAsync異步的去獲取鎖,然后再使用get獲取結(jié)果,如果結(jié)果為null代表獲取鎖成功,這里后面會(huì)講。

然后進(jìn)到tryAcquireAsync方法,在這里判斷了leaseTime是不是-1,如果我們自己設(shè)定了過(guò)期時(shí)間,那么就會(huì)以我們?cè)O(shè)置的為準(zhǔn),并且不會(huì)去開啟自動(dòng)續(xù)期。

如果是默認(rèn)的-1,那么異步獲取鎖之后,后面還會(huì)去開啟一個(gè)自動(dòng)續(xù)期的定時(shí)任務(wù)。

異步獲取鎖是通過(guò)tryLockInnerAsync這個(gè)方法實(shí)現(xiàn)的。第一個(gè)參數(shù)是30000,傳入的是commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(),點(diǎn)進(jìn)去可以看到

在這個(gè)方法里使用lua腳本的方式去執(zhí)行了set操作

這段lua腳本的意思是:

鎖不存在,加鎖成功,設(shè)置hash數(shù)據(jù)結(jié)構(gòu)鎖: 鎖名 -> 加鎖線程:id -> 加鎖次數(shù)(1)
鎖存在且是本線程的鎖 加鎖次數(shù)增加:鎖名 -> 加鎖線程:id -> 加鎖次數(shù)+1
鎖存在且不是本線程的鎖 加鎖失敗 返回鎖剩余過(guò)期時(shí)間

從這里也可以體現(xiàn)出此鎖的可重入,即某一線程獲取到鎖之后,那么這個(gè)線程再去獲取該鎖的話也可以成功

同時(shí)也可以如果返回為null那么說(shuō)明獲取鎖成功。

然后后面會(huì)判斷如果結(jié)果為null,就會(huì)去執(zhí)行scheduleExpirationRenewal(threadId)方法,進(jìn)去看一下

由于我們的Redission的分布式鎖是可重入鎖,所以這里會(huì)首先判斷一下是不是第一次加鎖,如果不是第一次則加鎖次數(shù)加 1 不會(huì)再開啟續(xù)期 因?yàn)榈谝淮渭渔i時(shí)調(diào)用

如果是第一次加鎖的話就回去調(diào)用renewExpiraton()去開啟自動(dòng)續(xù)期。

addThreadId:重入次數(shù)+1

renewExpiraton()開啟自動(dòng)續(xù)期這個(gè)方法里面創(chuàng)建了一個(gè)定時(shí)任務(wù),主要邏輯是通過(guò)renewExpirationAsync(threadId)方法去執(zhí)行續(xù)期邏輯,執(zhí)行成功后還會(huì)通過(guò)下面if (res) {renewExpiration();}方法遞歸調(diào)用。

注意到這個(gè)線程執(zhí)行的間隔是internalLockLeaseTime / 3,也就是30 / 3 = 10s

我們可以看一下renewExpirationAsync方法里面的邏輯

此lua腳本的意思是:當(dāng)前線程持有的鎖是否還存在 存在的話重新設(shè)置鎖的過(guò)期時(shí)間(默認(rèn) 30 秒)

至此加鎖的邏輯就追完了。

下面我們看一看釋放鎖的邏輯。其入口為:unlock方法,它會(huì)去調(diào)用unlockAsync方法。

unlockAsync里面掉了unlockInnerAsync方法去釋放鎖,

unlockInnerAsync方法點(diǎn)進(jìn)去我們可以看到它也是通過(guò)lua腳本的方式去釋放鎖。

若鎖不存在 返回 若鎖存在 加鎖次數(shù) -1 若加鎖次數(shù)仍不等于 0 (可重入),重新設(shè)置鎖的過(guò)期時(shí)間,返回 若加鎖次數(shù)減為 0,刪除鎖,同步發(fā)布釋放鎖事件,返回

以上就是一文詳解Redisson分布式鎖底層實(shí)現(xiàn)原理的詳細(xì)內(nèi)容,更多關(guān)于Redisson分布式鎖實(shí)現(xiàn)原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 后端java壓縮圖片超詳細(xì)圖文教程

    后端java壓縮圖片超詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于后端java壓縮圖片的相關(guān)資料,片壓縮是一種廣泛采用的技術(shù),它不僅能顯著減小文件大小,釋放更多存儲(chǔ)空間,還能提升圖片加載速度,避免長(zhǎng)時(shí)間等待,需要的朋友可以參考下
    2024-04-04
  • java編寫一個(gè)花名隨機(jī)抽取器的實(shí)現(xiàn)示例

    java編寫一個(gè)花名隨機(jī)抽取器的實(shí)現(xiàn)示例

    這篇文章主要介紹了java編寫一個(gè)花名隨機(jī)抽取器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java實(shí)現(xiàn)DES加解密算法解析

    Java實(shí)現(xiàn)DES加解密算法解析

    這篇文章主要介紹了Java實(shí)現(xiàn)DES加解密算法解析,結(jié)合完整實(shí)例形式分析了DES加密的相關(guān)原理,需要的朋友可以參考下。
    2016-10-10
  • java線程池實(shí)戰(zhàn)應(yīng)用步驟詳解

    java線程池實(shí)戰(zhàn)應(yīng)用步驟詳解

    這篇文章主要介紹了java線程池實(shí)戰(zhàn)應(yīng)用小結(jié),包括線程池的創(chuàng)建方式,本文給大家分享兩種方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2025-04-04
  • java應(yīng)用程序如何自定義log4j配置文件的位置

    java應(yīng)用程序如何自定義log4j配置文件的位置

    這篇文章主要介紹了java應(yīng)用程序如何自定義log4j配置文件的位置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java調(diào)用C++動(dòng)態(tài)庫(kù)超詳細(xì)步驟講解(附源碼)

    Java調(diào)用C++動(dòng)態(tài)庫(kù)超詳細(xì)步驟講解(附源碼)

    C語(yǔ)言因其高效和接近硬件的特性,時(shí)常會(huì)被用在性能要求較高或者需要直接操作硬件的場(chǎng)合,這篇文章主要介紹了Java調(diào)用C++動(dòng)態(tài)庫(kù)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • ThreadLocal工作原理及用法案例

    ThreadLocal工作原理及用法案例

    本文詳細(xì)講解了ThreadLocal工作原理及用法案例,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Java中枚舉的使用方法詳解

    Java中枚舉的使用方法詳解

    這篇文章主要介紹了Java中枚舉的使用方法詳解,比如我們想聲明一組季節(jié)的集合,那這里面最多有四種,即春夏秋冬,不允許有其他的季節(jié),那為了實(shí)現(xiàn)這種限制,體現(xiàn)出季節(jié)是固定的四個(gè)對(duì)象,我們可以使用枚舉,需要的朋友可以參考下
    2023-07-07
  • kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理

    kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理

    這篇文章主要為大家介紹了kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • java實(shí)現(xiàn)貪吃蛇小游戲

    java實(shí)現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07

最新評(píng)論