日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java实现Redis分布锁

發布時間:2025/4/16 java 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java实现Redis分布锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、背景:

在多線程環境下,通常會使用鎖來保證有且只有一個線程來操作共享資源。比如:

object obj = new object();
lock (obj)?
{?
//操作共享資源?
}

利用操作系統提供的鎖機制,可以確保多線程或多進程下的并發唯一操作。但如果在多機環境下就不能滿足了,當A,B兩臺機器同時操作C機器的共享資源時,就需要第三方的鎖機制來保證在分布式環境下的資源協調,也稱分布式鎖。

在分布式環境下(多節點主機)加鎖處理場景,如:秒殺、全局遞增ID等等,需要對資源(變量)同步互斥。大部分的解決方案是基于DB實現的,Redis為單進程單線程模式,采用隊列模式將并發訪問變成串行訪問,且多客戶端對Redis的連接并不存在競爭關系。由于Redis是單線程模型,命令操作原子性,所以利用這個特性可以很容易的實現分布式鎖。


2、Redis有三個最基本屬性來保證分布式鎖的有效實現:

安全性: 互斥,在任何時候,只有一個客戶端能持有鎖。
活躍性A:沒有死鎖,即使客戶端在持有鎖的時候崩潰,最后也會有其他客戶端能獲得鎖,超時機制。

活躍性B:故障容忍,只有大多數Redis節點時存活的,客戶端仍可以獲得鎖和釋放鎖。

使用Redis實現分布式鎖,有兩個重要函數需要介紹

1)SETNX命令(SET if Not eXists)
語法:
SETNX key value
功能:
當且僅當 key 不存在,將 key 的值設為 value ,并返回1;若給定的 key 已經存在,則 SETNX 不做任何動作,并返回0。


2)GETSET命令
語法:
GETSET key value
功能:
將給定 key 的值設為 value ,并返回 key 的舊值 (old value),當 key 存在但不是字符串類型時,返回一個錯誤,當key不存在時,返回nil。


3、代碼:

package ct.tool;import redis.clients.jedis.Jedis;public class RedisDisLock {private static final long expired = 1000;//1秒超時//上鎖public static boolean acquireLock(Jedis jedis,String lock) {// 1. 通過SETNX試圖獲取一個lockboolean success = false;long value = System.currentTimeMillis() + expired + 1; long acquired = jedis.setnx(lock, String.valueOf(value));jedis.expire(lock, 1);//設置1秒超時//SETNX成功,則成功獲取一個鎖if (acquired == 1) success = true;//SETNX失敗,說明鎖被其他客戶端保持,檢查其是否已經超時/*else {long oldValue = Long.valueOf(jedis.get(lock)); if (oldValue < System.currentTimeMillis()) {//超時//獲取上一個鎖到期時間,并設置現在的鎖到期時間,//只有一個線程才能獲取上一個線上的設置時間,因為jedis.getSet是同步的String getValue = jedis.getSet(lock, String.valueOf(value));if (getValue !=null) {if (Long.valueOf(getValue) == oldValue) success = true; else success = false;// 已被其他進程捷足先登了} }else //未超時,則直接返回失敗success = false;} */return success; }//釋放鎖public static void releaseLock(Jedis jedis,String lock) { //long current = System.currentTimeMillis(); // 避免刪除非自己獲取得到的鎖//if (current < Long.valueOf(jedis.get(lock)))jedis.del(lock); }}

代碼應用中,要共享的代碼段前加:

//枷鎖boolean lockFlag=true;while(lockFlag){//循環等待拿鎖if (RedisDisLock.acquireLock(jd,"o2o")) lockFlag=false;}
業務處理后,釋放:

RedisDisLock.releaseLock(jd, "o2o");


總結

以上是生活随笔為你收集整理的Java实现Redis分布锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。