Redisson是基于Redis實現的客戶端庫,提供了多種Java并發API映射到Redis中,也實現了各種分布式服務,其中就有各種分布式鎖的實現。
Redisson鎖彌補了SETNX鎖的的局限性,實現了可重入、可重試和超時續約的功能。
-
可重入:利用redis的 hash 結構記錄線程 id 和重入次數。每次獲取鎖時,先判斷鎖是否存在,如果不存在,則直接獲取,如果已經存在,且線程標識為當前線程,則可以再次獲取,并將重入次數加 1。釋放鎖時,每釋放一次,重入次數減 1,直至重入次數減為 0,則證明所有的業務已經執行結束,則可以直接釋放鎖。整個過程是采用lua腳本實現的。
-
可重試:利用信號量和 PubSub 功能實現等待、喚醒,獲取鎖失敗的重試機制。在第一次嘗試獲取鎖失敗后,并不是立即失敗,而是去等待釋放鎖的信號(利用了 Redis 中 PubSub 機制)。而獲取鎖成功的線程在釋放鎖的時候,就會向等待中的線程發送一條消息,等待中的線程捕獲到消息后,就可以重新嘗試獲取鎖。如果重試失敗,則會繼續等待釋放鎖的信號,然后再去重試。當然,重試并不是無限次的,會有一個等待時間,如果超過等待時間,就結束重試。
-
超時續約:利用 watchDog,每隔一段時間(releaseTime/3),重置超時時間。簡單來說,就是在獲取鎖成功后,會開啟一個定時任務,該定時任務每隔一段時間就會重置鎖的超時時間,這樣鎖的超時時間就會重新計時。
參考1
參考2