redis分散式鎖的實現

空空大首領發表於2023-02-23

一.正常加鎖

當兩個使用者同時註冊一個使用者名稱時,為保證使用者名稱不能重複,因此對其註冊的使用者名稱加鎖。

具體步驟:

獲得使用者註冊的使用者名稱,進行判斷,如果為空則對其進行加鎖,儲存到資料庫,釋放鎖資源。

 

二.執行緒出現阻塞

當A執行緒加鎖後出現阻塞時,導致資料還沒有存到資料庫,鎖的時間便會失效。

B執行緒便會執行,對資料進行加鎖,成功後儲存到資料庫,而這時A執行緒啟動,將資料儲存到資料庫,這時的資料便又會重複。

解決方法:

對鎖進行延期,加鎖成功後新建一個守護執行緒,監控鎖的過期時間,如果這個時間小於設定的時間,則會自動延期

問題:1.為何使用守護執行緒

不一定要用守護執行緒,只要能保證對鎖進行延期即可

2.為何要設定過期時間

為了避免出現特殊情況,導致鎖一直留在redis中,不能釋放,比如:斷電,刪除鎖失敗

 

三.網上對執行緒的說法

 極端情況下以上的思路還是可能出現問題,比如:

  1. 有兩個執行緒A,B一前一後執行
  2. A執行緒正常執行,但是執行業務時間較長,並且守護執行緒阻塞或者延期失敗,導致鎖自動過期
  3. B執行緒又來加鎖,之後A執行緒繼續執行,最後釋放鎖,其實A執行緒加的鎖已經過期,釋放的是B執行緒的鎖

解決方法:

  • 在執行setIfAbsent方法時,給key設定一個唯一值,如加uuid
  • 在釋放鎖時,先判斷value對不對,再釋放

但是這個說法不是我們加鎖的初衷,而且沒意義,我們加鎖就是為了:避免多個執行緒同時執行這段程式碼,但網上這個說法明顯是支援多執行緒同時執行

相關文章