黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注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) 瀏覽3373次

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í)沒有人持有鎖,加鎖成功:

127.0.0.1:6379> setnx lock 1
(integer) 1

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

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

存在問題:

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

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

解決方案:setnx expire

Redis setnx expire

為了解決上述死鎖問題,我們?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

存在問題:

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

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

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

解決方案:RedissonLock

RedissonLock

上述兩個(gè)問題,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秒去檢查鎖是否釋放,如果沒有釋放,把失效時(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分布式鎖面試題

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

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

解決方案:RedLock

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

如果業(yè)務(wù)能接受極端情況下存在互斥失敗問題,并且對(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ù)器端沒有在規(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)槟承┰颍@取鎖失敗(沒有在至少N/2+1個(gè)Redis實(shí)例取到鎖或者取鎖時(shí)間已經(jīng)超過(guò)了有效時(shí)間),客戶端應(yīng)該在所有的Redis實(shí)例上進(jìn)行解鎖(即便某些Redis實(shí)例根本就沒有加鎖成功)。

缺點(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)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 视频一本大道香蕉久在线播放 | 色视频在线观看免费 | 在线亚洲一区 | 日韩精品久久久久影院 | 最近2019中文免费字幕 | 可以免费看的黄色网址 | 日韩免费观看视频 | 大杳蕉伊人狼人久久一本线 | 成人狠狠色综合 | 久久女同互慰一区二区三区 | 在线观看免费午夜大片 | 日日操影院 | 国产精品国产精品国产三级普 | 欧美日韩国产网站 | 亚洲国产精品成人综合久久久 | 亚洲欧美一区二区三区在线 | 日日好吊妞 | 天海翼一区二区三区四区 | 午夜一级做a爰片久久毛片 午夜一级免费视频 | 欧美一级视频在线 | 看全色黄大色黄女片爽毛片 | 日韩射| 99久9在线视频 | 午夜毛片视频高清不卡免费 | 国产一级一片免费播放 | 激情伊人| 中文字幕天天躁日日躁狠狠 | 国产亚洲女在线线精品 | 久久午夜精品视频 | 久久夜色视频 | 日本在线免费 | 国产亚洲欧美在线视频 | 亚洲视频在线观看免费 | 成人综合在线视频免费观看 | 日韩大片免费观看视频播放 | 天天射天天操天天色 | 日韩激情影院莉莉 | 一区二区三区在线视频播放 | 生活一级毛片 | 日韩国产欧美在线观看一区二区 | 久久成人18免费 |