一.正常加鎖
當兩個用戶同時注冊一個用戶名時,為保證用戶名不能重復,因此對其注冊的用戶名加鎖,
具體步驟:
獲得用戶注冊的用戶名,進行判斷,如果為空則對其進行加鎖,保存到資料庫,釋放鎖資源,
二.執行緒出現阻塞
當A執行緒加鎖后出現阻塞時,導致資料還沒有存到資料庫,鎖的時間便會失效,
B執行緒便會執行,對資料進行加鎖,成功后保存到資料庫,而這時A執行緒啟動,將資料保存到資料庫,這時的資料便又會重復,
解決方法:
對鎖進行延期,加鎖成功后新建一個守護執行緒,監控鎖的過期時間,如果這個時間小于設定的時間,則會自動延期
問題:1.為何使用守護執行緒
不一定要用守護執行緒,只要能保證對鎖進行延期即可
2.為何要設定過期時間
為了避免出現特殊情況,導致鎖一直留在redis中,不能釋放,比如:斷電,洗掉鎖失敗
三.網上對執行緒的說法
極端情況下以上的思路還是可能出現問題,比如:
- 有兩個執行緒A,B一前一后執行
- A執行緒正常執行,但是執行業務時間較長,并且守護執行緒阻塞或者延期失敗,導致鎖自動過期
- B執行緒又來加鎖,之后A執行緒繼續執行,最后釋放鎖,其實A執行緒加的鎖已經過期,釋放的是B執行緒的鎖
解決方法:
- 在執行setIfAbsent方法時,給key設定一個唯一值,如加uuid
- 在釋放鎖時,先判斷value對不對,再釋放
但是這個說法不是我們加鎖的初衷,而且沒意義,我們加鎖就是為了:避免多個執行緒同時執行這段代碼,但網上這個說法明顯是支持多執行緒同時執行
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544827.html
標籤:其他
上一篇:go 神奇的錯誤 time.Now().Format("2006-01-02 13:04:05") 比北京時間大8小時
下一篇:FTP客戶端c代碼功能實作
