国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

基于redis實(shí)現(xiàn)分布式鎖思考

Tecode / 1989人閱讀

摘要:分布式鎖基于實(shí)現(xiàn)分布式鎖思考幾個(gè)問(wèn)題鎖為什么不能應(yīng)用于分布式鎖雖然能夠解決同步問(wèn)題,但是每次只有一個(gè)線(xiàn)程訪(fǎng)問(wèn),并且鎖屬于鎖,僅適用于單點(diǎn)部署然而分布式需要部署多臺(tái)實(shí)例,屬于不同的線(xiàn)程對(duì)象使用中實(shí)現(xiàn)分布式鎖。

分布式鎖
基于redis實(shí)現(xiàn)分布式鎖思考幾個(gè)問(wèn)題?

synchronized鎖為什么不能應(yīng)用于分布式鎖?
synchronized雖然能夠解決同步問(wèn)題,但是每次只有一個(gè)線(xiàn)程訪(fǎng)問(wèn),并且synchronized鎖屬于JVM鎖,僅適用于單點(diǎn)部署;然而分布式需要部署多臺(tái)實(shí)例,屬于不同的JVM線(xiàn)程對(duì)象

使用redis中setnx實(shí)現(xiàn)分布式鎖。

//設(shè)置分布式鎖
String lockKey = "product_001_key";
//語(yǔ)義:如何不存在則存入緩存中,且返回true;
//否則已存在,則返回false即加鎖失敗
Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "product_001_lock");
if (!result) {
  //沒(méi)有加鎖成功,則返回提示等
}
try{
  
}catch() {
  
}finally{
  //釋放鎖
  stringRedisTemplate.delete(lockKey);
}

針對(duì)以上設(shè)置分布式鎖思考一下問(wèn)題?

1.如果突然服務(wù)器宕機(jī),那么必然造成鎖無(wú)法釋放,即造成死鎖?
解決方案:設(shè)置超時(shí)時(shí)間。

//設(shè)置分布式鎖
String lockKey = "product_001_key";
Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "product_001_lock");
//設(shè)置鎖超時(shí)時(shí)間30s
stringRedisTemplate.expire(lockKey,30, TimeUnit.SECONDS);
if (!result) {
//沒(méi)有加鎖成功,則返回提示等
}
try{

}catch() {

}finally{
//釋放鎖
stringRedisTemplate.delete(lockKey);
}
2.加鎖和設(shè)置超時(shí)時(shí)間中間引起服務(wù)器宕機(jī),則一樣會(huì)導(dǎo)致死鎖。

Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "product_001_lock");
//------服務(wù)器宕機(jī),則超時(shí)時(shí)間未設(shè)置成功-------
//設(shè)置鎖超時(shí)時(shí)間30s
stringRedisTemplate.expire(lockKey,30, TimeUnit.SECONDS);

解決方案:原子性操作,即同時(shí)加鎖和設(shè)置超時(shí)時(shí)間;

即上面的代碼合并成一句操作:

Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey,"product_001_lock", 30, TimeUnit.SECONDS)

3.思考超時(shí)時(shí)間設(shè)置是否合理呢?即線(xiàn)程執(zhí)行時(shí)間和鎖超時(shí)時(shí)間并非一致。
場(chǎng)景:假設(shè)設(shè)置加鎖超時(shí)時(shí)間10s;

高并發(fā)場(chǎng)景下,線(xiàn)程A執(zhí)行時(shí)間為15s,redis依據(jù)超時(shí)時(shí)間,將其線(xiàn)程A加的鎖釋放掉;然后線(xiàn)程B獲取鎖,并加鎖成功,此時(shí)線(xiàn)程A執(zhí)行結(jié)束,執(zhí)行finally代碼塊就會(huì)將線(xiàn)程B加的鎖釋放。

解決方案:設(shè)置線(xiàn)程隨機(jī)ID,釋放鎖時(shí)判斷是否為當(dāng)前線(xiàn)程加的鎖,即使存在線(xiàn)程A因線(xiàn)程執(zhí)行時(shí)間超時(shí)被動(dòng)釋放其鎖,但至少保證當(dāng)前超時(shí)線(xiàn)程不會(huì)釋放其他線(xiàn)程加的鎖。但是面對(duì)線(xiàn)程執(zhí)行時(shí)間大于設(shè)置的超時(shí)時(shí)間,也是會(huì)存在并發(fā)問(wèn)題。


String lockKey = "product_001";
String clientId = UUID.randomUUID().toString();
//設(shè)置超時(shí)時(shí)間,且加鎖和設(shè)置線(xiàn)程ID
Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey,clientId, 30, TimeUnit.SECONDS)`
  
if (!result) {
  //沒(méi)有加鎖成功,則返回提示等
}
try{
  
}catch() {
  
}finally{
  //釋放鎖:加鎖線(xiàn)程ID和當(dāng)前執(zhí)行線(xiàn)程ID相同,才允許釋放鎖
 if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey))){
        stringRedisTemplate.delete(lockKey);
    }
} 

4.上面場(chǎng)景解決方案:加鎖續(xù)命即續(xù)線(xiàn)程鎖超時(shí)時(shí)間
解決方案:加鎖成功時(shí),開(kāi)啟一個(gè)后臺(tái)線(xiàn)程,每隔10s(自定義)判斷當(dāng)前線(xiàn)程是否還持有鎖,持有鎖則再續(xù)命30s等

Redission實(shí)現(xiàn)分布式鎖
實(shí)現(xiàn)原理流程:

String lockKey = "product_001";
        //獲取鎖對(duì)象,并未加鎖
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            // **此時(shí)加鎖**,實(shí)現(xiàn)鎖續(xù)命功能
            redissonLock.lock();
            int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock")); 
            if (stock > 0) {
                int realStock = stock - 1;
                stringRedisTemplate.opsForValue().set("stock", realStock + ""); 
                System.out.println("扣減成功,剩余庫(kù)存:" + realStock + "");
            } else {
                System.out.println("扣減失敗,庫(kù)存不足");
            }
        }finally {
          //釋放鎖
            redissonLock.unlock();
        }

總結(jié)
綜上,設(shè)計(jì)實(shí)現(xiàn)分布式鎖需要滿(mǎn)足一下條件:

1.互斥性;在任意時(shí)刻,只有一個(gè)客戶(hù)端能持有鎖。

2.不能發(fā)生死鎖;即使存在一個(gè)線(xiàn)程持有鎖的期間崩潰而沒(méi)有主動(dòng)解鎖,也能保證后續(xù)其他線(xiàn)程能加鎖。

3.加鎖和解鎖必須是同一個(gè)線(xiàn)程。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/125953.html

相關(guān)文章

  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    BicycleWarrior 評(píng)論0 收藏0
  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    tommego 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<