Redis學習(二) —— 分佈式鎖

一個操做須要進行讀變量,寫變量兩個步驟,多個相同的操做同時進行就會出現併發問題。由於讀取和寫入兩個變量不是原子操做。html

分佈式鎖

分佈式鎖本質上要實現的目標就是在 Redis 裏面佔一個「茅坑」,當別的進程也要來佔時,發現已經有人蹲在那裏了,就只好放棄或者稍後再試。算法

佔坑通常是使用 setnx(set if not exists) 指令,只容許被一個客戶端佔坑。先來先佔, 用完了,再調用 del 指令釋放茅坑。併發

加鎖分佈式

setnx lock:a true

釋放鎖線程

del lock:a

爲了不加鎖後,中間操做出現異常,最後沒有釋放鎖的問題,須要給鎖設置一個超時時間。設計

setnx lock:a true
expire lock:a 5

出現另外一個問題,上面的操做也有可能失敗,例如設置過時時間失敗。code

爲了解決上述的問題,Redis2.8增長了set指令的擴展參數,htm

set lock:a true ex 5 nx

超時問題

若是執行代碼的時間太長,超出了鎖的超時限制,就會由其餘線程得到鎖。會致使代碼不能嚴格被執行。爲了不這個狀況,進行加鎖的執行代碼儘可能不要選擇執行時間過長的。對象

可重入性

可重入性指的是線程在持有鎖的狀況下,再次請求加鎖。blog

問題,爲什麼要設計可重入這一個特性?

搞清楚幾個概念:可重入鎖、公平鎖、非公平鎖。

可重入鎖:
線程1執行 synchronized A()方法,A()方法調用synchronized B()方法,當線程1獲取到A方法對應的對象鎖以後,再去調用B方法,就不須要從新申請鎖。

公平鎖:
多個線程等待鎖,當鎖釋放後,等待該鎖時間最久的(或者說最早申請鎖的),應該得到鎖。

非公平鎖:
多個線程等待鎖,不按照等待鎖的時間或申請鎖的前後順序,來得到鎖。

Redlock 算法

參考文檔

[1]: 《Redis 深度歷險:核心原理與應用實踐》
[2]: 經過一個故事理解可重入鎖的機制
[3]: JAVA鎖機制-可重入鎖,可中斷鎖,公平鎖,讀寫鎖,自旋鎖
[4]: 80% 人不知道的 Redis 分佈式鎖的正確實現方式(Java 版)

相關文章
相關標籤/搜索