一、使用
1、pom.xml匯入依賴
2、配置檔案
3、使用類
二、原理
obtain方法
主要是根據lockKey去查locks這個map中是否已經存在這個key
如果存在就返回內部類RedisLock
如果不存在就建立一個RedisLock,以lockKey為key,RedisLock為value放入map中
備註:每個分散式應用自己都會建立一個RedisLockRegistry例項,同一個應用的多個執行緒共享RedisLock類
tryLock方法
主要過程
先獲得本地鎖,拿不到直接返回失敗
當前時間還沒過期並且還沒拿到redis鎖,睡眠100ms繼續重試
如果拿到redis鎖,結束迴圈,返回成功
如果超時了還沒拿到,釋放鎖,返回失敗
拿redis鎖的過程
通過obtainLock方法,執行lua指令碼來獲取
redisTemplate.execute()引數說明:
第一個obtainLockScript引數就是要執行的lua指令碼;
第二個引數就是表示在指令碼中所用到的那些 Redis 鍵(key),這些鍵名引數可以在 Lua 中通過全域性變數 KEYS 陣列,用1為基址的形式訪問( KEYS[1] , KEYS[2] ,以此類推);
第三個參是附加引數 arg [arg …] ,可以在 Lua 中通過全域性變數 ARGV 陣列訪問,訪問的形式和 KEYS 變數類似( ARGV[1] 、 ARGV[2] ,諸如此類)
為什麼要用本地鎖
- 為了可重入
- 為了減輕redis伺服器的壓力
為什麼要用lua指令碼
- 保證原子性
- 減少網路開銷
- 替代redis的事務功能
unlock方法
釋放鎖的過程
1、判斷是否是當前執行緒持有鎖,如果不是,拋異常(本地鎖)
2、判斷當前執行緒持有鎖的計數
如果當前執行緒持有鎖的計數 > 1,說明本地鎖被當前執行緒多次獲取,這時只會釋放本地鎖,釋放之後當前執行緒持有鎖的計數-1。
否則,釋放本地鎖和redis鎖。