Redisson 分布式鎖源碼之八:MultiLock 加鎖與鎖釋放
前言
基于 Redis 的 Redisson 分布式聯鎖 RedissonMultiLock 對象可以將多個 RLock 對象關聯為一個聯鎖,每個 RLock 對象實例可以來自于不同的 Redisson 實例。
當然,這是官網的介紹,具體是什么?一起看看聯鎖 MultiLock 使用以及源碼吧!
1MultiLock 使用
按照官方文檔的說法,這里 Redisson 客戶端可以不是同一個。當然,一般工作中也不會說不用一個客戶端吧。
2加鎖
在閱讀 MultiLock 加鎖之前,小伙伴應該已經閱讀過普通加鎖的相關文章。
源碼入口:org.redisson.RedissonMultiLock#lock()
默認超時時間 leaseTime 沒有設置,所以為 -1。
這塊方法太長,咱們拆分進行閱讀。
- 基礎等待時間 baseWaitTime = 鎖數量 * 1500,在這里就是 4500 毫秒;
- leaseTime == -1 所以 waitTime = baseWaitTime,也就是 4500;
- while (true) 調用 tryLock 加鎖,直到成功。
調用 tryLock 方法,其中參數 waitTime = 4500,leaseTime = -1,unit = MILLISECONDS。
下面看一下 tryLock 里面有什么邏輯?
leaseTime != -1 不滿足,這部分直接跳過。
waitTime != -1 條件滿足,remainTime = 4500,lockWaitTime = 4500。
所以,failedLocksLimit() 這個方法直接返回 0,就是必須全部加鎖成功。
這里才是重點:
遍歷所有的鎖,依次加鎖。
加鎖邏輯就和可重入鎖加鎖并無區別了。所以 Lua 腳本就不進行分析了。
上面就是 tryLock 加鎖之后的結果。
加鎖成功,則將成功的鎖放進 acquiredLocks 集合中;
加鎖失敗,需要判斷 failedLocksLimit,因為這里是 0,所以會直接對成功加鎖集合 acquiredLocks 中的所有鎖執行鎖釋放,同時清空成功集合,恢復迭代器。
每次加鎖之后,會更新鎖剩余時間 remainTime,如果 remainTime 小于等于 0 了,則說明加鎖超時,直接返回 false。
這樣就會執行外部的 while (true) 邏輯,然后重新再走一遍 RedissonMultiLock#tryLock。
3鎖釋放
看完加鎖邏輯,鎖釋放就更容易理解了。
直接遍歷釋放鎖即可,lock.unlockAsync() 是調用的 RedissonBaseLock#unlockAsync() 方法。
4總結
根據我的理解,畫圖如下:
總體而言,就是將 key1、key2、key3 …… keyN 放到一個 List 集合中,然后迭代循環加鎖,直到所有的都成功。解鎖的時候就是再遍歷鎖進行釋放鎖。
本文轉載自微信公眾號「程序員小航」,可以通過以下二維碼關注。轉載本文請聯系程序員小航公眾號。