日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Redisson分布式鎖源碼之公平鎖排隊(duì)加鎖

Redisson 分布式鎖源碼之公平鎖排隊(duì)加鎖

作者:程序員小航 2021-07-01 09:42:08

前端
分布式
Redis Redis sorted set 有序集合數(shù)據(jù)結(jié)構(gòu):存放等待線程的順序,分?jǐn)?shù) score 用來是等待線程的超時(shí)時(shí)間戳。

創(chuàng)新互聯(lián)建站成立10余年來,這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、網(wǎng)站策劃、網(wǎng)頁設(shè)計(jì)、國(guó)際域名空間、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。網(wǎng)站是否美觀、功能強(qiáng)大、用戶體驗(yàn)好、性價(jià)比高、打開快等等,這些對(duì)于網(wǎng)站建設(shè)都非常重要,創(chuàng)新互聯(lián)建站通過對(duì)建站技術(shù)性的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。

前言

在上一篇文章中已經(jīng)分析過公平鎖的加鎖源碼,并得出結(jié)論:

Redis Hash 數(shù)據(jù)結(jié)構(gòu):存放當(dāng)前鎖,Redis Key 就是鎖,Hash 的 field 是加鎖線程,Hash 的 value 是 重入次數(shù);

Redis List 數(shù)據(jù)結(jié)構(gòu):充當(dāng)線程等待隊(duì)列,新的等待線程會(huì)使用 rpush 命令放在隊(duì)列右邊;

Redis sorted set 有序集合數(shù)據(jù)結(jié)構(gòu):存放等待線程的順序,分?jǐn)?shù) score 用來是等待線程的超時(shí)時(shí)間戳。

現(xiàn)在看一下加鎖失敗被放到等待隊(duì)列之后,線程是如何處理的?

1排隊(duì)等鎖

源碼入口:org.redisson.RedissonLock#lock(long, java.util.concurrent.TimeUnit, boolean)。

線程進(jìn)入排隊(duì)之后,在 Java 代碼中會(huì) while (true) 一直循環(huán)調(diào)用 tryAcquire,嘗試獲取鎖。

最終還是來到 RedissonFairLock#tryLockInnerAsync 方法中。

方便起見,重新貼一下 Lua 腳本,以及腳本的參數(shù)含義。

  1. KEYS[1]:加鎖的名字,anyLock;
  2. KEYS[2]:加鎖等待隊(duì)列,redisson_lock_queue:{anyLock};
  3. KEYS[3]:等待隊(duì)列中線程鎖時(shí)間的 set 集合,redisson_lock_timeout:{anyLock},是按照鎖的時(shí)間戳存放到集合中的;
  4. ARGV[1]:鎖超時(shí)時(shí)間 30000
  5. ARGV[2]:UUID:ThreadId 組合 a3da2c83-b084-425c-a70f-5d9a08b37f31:1
  6. ARGV[3]:threadWaitTime 默認(rèn) 300000
  7. ARGV[4]:currentTime 當(dāng)前時(shí)間戳

源碼分析

第一部分,while 循環(huán):

  1. 從等待隊(duì)列 redisson_lock_queue:{anyLock} 中獲取第一個(gè)等待線程;
  2. 從等待線程超時(shí)集合 redisson_lock_timeout:{anyLock} 中獲取第一個(gè)等待線程的分?jǐn)?shù);
  3. 沒有超時(shí),直接結(jié)束,超時(shí)了,則直接移除。

第二部分,當(dāng)前鎖存在,直接跳過。

第三部分,當(dāng)前鎖不是持鎖線程,直接跳過。

第四部分,

直接返回當(dāng)前鎖還有多久到期。

當(dāng)前 Redisson 版本為 3.15.6,不同版本的略有不同。

隊(duì)列重排

這里不存在重新排序,因?yàn)楣俜秸J(rèn)為這是一個(gè) bug,重新進(jìn)行了修復(fù)。

具體可以閱讀:Justin Corpron 2019/5/10, 04:13 Fix timeout drift in RedissonFairLock

最大的變化就是增加了第四部分。

圖僅僅代表兩個(gè)版本的差別,并不是代表這個(gè)版本才修改。

2總結(jié)

當(dāng)線程獲取鎖失敗,進(jìn)入到等待隊(duì)列時(shí),ttl != null,在 Java 代碼中會(huì)不斷嘗試獲取鎖。

當(dāng)鎖不存在且當(dāng)前線程是在等待隊(duì)列頭時(shí),直接獲得鎖。這個(gè)排隊(duì)的過程就是公平鎖的提現(xiàn)。

本文轉(zhuǎn)載自微信公眾號(hào)「程序員小航」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序員小航公眾號(hào)。


網(wǎng)站名稱:Redisson分布式鎖源碼之公平鎖排隊(duì)加鎖
當(dāng)前URL:http://www.5511xx.com/article/cogejjs.html