大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國(guó)咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) 學(xué)習(xí)攻略 職業(yè)指南 還是一樣高頻出現(xiàn)的Java分布式鎖面試題

還是一樣高頻出現(xiàn)的Java分布式鎖面試題

更新時(shí)間:2023-02-15 16:00:07 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽3364次

1.為什么需要分布式鎖?

public synchronized void test() {
    System.out.println("獲取到鎖");
}
public void test2() {
     synchronized (Test.class) {
          System.out.println("獲取到鎖");
     }
}

假設(shè)我們把上述代碼部署到多臺(tái)服務(wù)器上,這個(gè)互斥鎖還能生效嗎?答案是否定的,這時(shí)分布式鎖應(yīng)運(yùn)而生。

2.Redis分布式鎖?

接下來(lái)我給大家講解完整的演變過(guò)程,讓大家更深刻的理解分布式鎖。

java分布式鎖面試題

Redis setnx

線程1申請(qǐng)加鎖,這時(shí)沒(méi)有人持有鎖,加鎖成功:

127.0.0.1:6379> setnx lock 1
(integer) 1

線程2申請(qǐng)加鎖,此時(shí)發(fā)現(xiàn)有人持有鎖未釋放,加鎖失?。?/p>

127.0.0.1:6379> setnx lock 1
(integer) 0

線程1執(zhí)行完成業(yè)務(wù)邏輯后,執(zhí)行DEL命令釋放鎖:

127.0.0.1:6379> del lock
(integer) 1

存在問(wèn)題:

①假設(shè)線程1執(zhí)行到一半,系統(tǒng)掛了,這時(shí)鎖還沒(méi)釋放,就會(huì)造成死鎖。

②如果Redis加鎖后,Master還沒(méi)同步給Slave就掛了,會(huì)導(dǎo)致有兩個(gè)客戶端獲取到鎖

解決方案:setnx expire

Redis setnx expire

為了解決上述死鎖問(wèn)題,我們?cè)趕etnx后,給這個(gè)key加上失效時(shí)間。

此時(shí)線程1加鎖的代碼改成:

127.0.0.1:6379> setnx lock 1 ## 加鎖
(integer) 1
127.0.0.1:6379> expire lock 3 ## 設(shè)置 key 3秒失效
(integer) 1

存在問(wèn)題:

①假設(shè)setnx lock 1執(zhí)行成功了,但是expire lock 3執(zhí)行失敗了,還是會(huì)存在死鎖問(wèn)題,這兩個(gè)命令需要保證原子性。

②失效時(shí)間是我們寫死的,不能自動(dòng)續(xù)約,如果業(yè)務(wù)執(zhí)行時(shí)間超過(guò)失效時(shí)間,會(huì)出現(xiàn)線程1還在執(zhí)行,線程2就加鎖成功了,并有沒(méi)達(dá)到互斥效果。

③如果Redis加鎖后,Master還沒(méi)同步給Slave就掛了,會(huì)導(dǎo)致有兩個(gè)客戶端獲取到鎖

解決方案:RedissonLock

RedissonLock

上述兩個(gè)問(wèn)題,RedissonLock都解決了,我通過(guò)源碼給大家剖析,看RedissonLock是如何解決的,基礎(chǔ)好的小伙伴可以好好讀讀源碼,其實(shí)RedissonLock源碼也不難。

我先寫結(jié)論,基礎(chǔ)較弱的小伙伴,只要記得結(jié)論就行:

java分布式鎖面試題

①RedisssonLock底層使用的是lua腳本執(zhí)行的redis指令,lua腳本可以保證加鎖和失效指令的原子性。

②RedisssonLock底層有個(gè)看門狗機(jī)制,加鎖成功后,會(huì)開啟一個(gè)定時(shí)調(diào)度任務(wù),每隔10秒去檢查鎖是否釋放,如果沒(méi)有釋放,把失效時(shí)間刷新成30秒。這樣鎖就可以一直續(xù)期,不會(huì)釋放。

我看的是3.12.5版本源碼,不同版本實(shí)現(xiàn)上可能存在一些差異。

應(yīng)用程序加鎖代碼:

RLock lock = redissonLock.getLock("anyLock");
lock.lock();

RedissonLock加鎖核心代碼:

java分布式鎖面試題

RedissonLock獲取鎖核心代碼:

java分布式鎖面試題

底層加鎖邏輯:

java分布式鎖面試題

KEYS[1] = anyLock,鎖的名稱。

ARGV[1] = 30000,失效時(shí)間,通過(guò)lockWatchdogTimeout配置。

ARGV[2] = c1b51ddb-1505-436c-a308-b3b75b4bd407:1,他是ConnectionManager的ID,我們可以簡(jiǎn)單的把它理解為一個(gè)客戶端的一個(gè)線程對(duì)應(yīng)的唯一標(biāo)志性。

RedissonLock解鎖核心代碼:

java分布式鎖面試題

存在問(wèn)題:如果redis是單節(jié)點(diǎn),存在單節(jié)點(diǎn)故障問(wèn)題;如果做主從架構(gòu),Redis加鎖后,Master還沒(méi)同步給Slave就掛了,會(huì)導(dǎo)致有兩個(gè)客戶端獲取到鎖

有小伙伴問(wèn)我,如果這里我用集群會(huì)存在這個(gè)問(wèn)題嗎?集群的本質(zhì)是分片,這個(gè)key最終還是會(huì)落到某個(gè)具體的節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)要么是單獨(dú)存在,要么是主從架構(gòu),所以還是會(huì)存在上述問(wèn)題。

解決方案:RedLock

補(bǔ)充:雖然RedLock可以解決上述問(wèn)題,但是在生產(chǎn)環(huán)境中我們很少使用,因?yàn)樗渴鸪杀竞芨?,相比RedissonLock性能也略微有所下降?。

如果業(yè)務(wù)能接受極端情況下存在互斥失敗問(wèn)題,并且對(duì)性能要求比較高,我們會(huì)選擇RedissonLock,并做好響應(yīng)?的兜底方案。

如果業(yè)務(wù)對(duì)數(shù)據(jù)要求絕對(duì)正確,?我們會(huì)采用Zookeeper來(lái)做分布式鎖。?

Redlock

我們假設(shè)有5個(gè)完全相互獨(dú)立的Redis Master單機(jī)節(jié)點(diǎn),所以我們需要在5臺(tái)機(jī)器上面運(yùn)行這些實(shí)例,如下圖所示(請(qǐng)注意這張圖中5個(gè)Master節(jié)點(diǎn)完全相互獨(dú)立)

為了取到鎖,客戶端應(yīng)該執(zhí)行以下操作:

java分布式鎖面試題

①獲取當(dāng)前Unix時(shí)間,以毫秒為單位。

②依次嘗試從N個(gè)Master實(shí)例使用相同的key和隨機(jī)值獲取鎖(假設(shè)這個(gè)key是LOCK_KEY)。當(dāng)向Redis設(shè)置鎖時(shí),客戶端應(yīng)該設(shè)置一個(gè)網(wǎng)絡(luò)連接和響應(yīng)超時(shí)時(shí)間,這個(gè)超時(shí)時(shí)間應(yīng)該小于鎖的失效時(shí)間。例如你的鎖自動(dòng)失效時(shí)間為10秒,則超時(shí)時(shí)間應(yīng)該在5-50毫秒之間。這樣可以避免服務(wù)器端Redis已經(jīng)掛掉的情況下,客戶端還在死死地等待響應(yīng)結(jié)果。如果服務(wù)器端沒(méi)有在規(guī)定時(shí)間內(nèi)響應(yīng),客戶端應(yīng)該盡快嘗試另外一個(gè)Redis實(shí)例。

③客戶端使用當(dāng)前時(shí)間減去開始獲取鎖時(shí)間(步驟1記錄的時(shí)間)就得到獲取鎖使用的時(shí)間。當(dāng)且僅當(dāng)從大多數(shù)的Redis節(jié)點(diǎn)都取到鎖,并且使用的時(shí)間小于鎖失效時(shí)間時(shí),鎖才算獲取成功。

④如果取到了鎖,key的真正有效時(shí)間等于有效時(shí)間減去獲取鎖所使用的時(shí)間(步驟3計(jì)算的結(jié)果)。

⑤如果因?yàn)槟承┰?,獲取鎖失敗(沒(méi)有在至少N/2+1個(gè)Redis實(shí)例取到鎖或者取鎖時(shí)間已經(jīng)超過(guò)了有效時(shí)間),客戶端應(yīng)該在所有的Redis實(shí)例上進(jìn)行解鎖(即便某些Redis實(shí)例根本就沒(méi)有加鎖成功)。

缺點(diǎn):像我們系統(tǒng),并發(fā)量比較大,生產(chǎn)環(huán)境必須要做分片才能扛住并發(fā),像上述方案,我們需要準(zhǔn)備5個(gè)Redis集群,這種機(jī)器成本是非常高的。

以上就是“還是一樣高頻出現(xiàn)的Java分布式鎖面試題”,你能回答上來(lái)嗎?如果想要了解更多的Java面試題相關(guān)內(nèi)容,可以關(guān)注動(dòng)力節(jié)點(diǎn)Java官網(wǎng)。

提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)

  • 全國(guó)校區(qū) 2025-06-26 搶座中
免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 国产精品一国产精品 | 亚洲国产二区三区 | 免费精品久久久视频 | 99这里只有精品视频 | 欧美理论片在线观看 | a一级毛片免费播放 | 99j久久精品久久久久久 | 中国jizz妇女jizz妇女 | 久久成人在线 | 日韩成人免费aa在线看 | 国产免费福利 | 黄色wwwwww| 婷婷综合色 | 日日干日日摸 | 国内精品自在欧美一区 | 内衣办公室动漫久久影院 | 欧美高清日韩 | 插吧插吧综合网 | 亚洲一级在线观看 | 奇米色第四色 | 国产日产精品久久久久快鸭 | 成年人免费网址 | 亚洲热在线 | 久久精品一区二区三区资源网 | 久久综合狠狠综合久久 | 最新国产精品精品视频 | 色综合欧美色综合七久久 | 四虎影视免费看 | 酒色网站 | 四虎国产精品永久地址99新强 | 亚洲欧美成人中文在线网站 | 国产99小视频 | 欧美国产亚洲18 | 久久精品亚洲精品一区 | 97爱爱爱 | 国产午夜视频在线观看第四页 | 一级毛片特级毛片黄毛片 | 日日摸夜夜摸无需播放器 | 日本又黄又爽又色的视频免费 | 欧美精品九九99久久在观看 | 久久精品国产精品亚洲 |