Java 中常見的細粒度鎖實現
阿新 • • 發佈:2020-11-23
上篇文章大致說了下 ReentrantLock 類的使用,對 ReentrantLock 類有了初步的認識之後讓我們一起來看下基於 ReentrantLock 的幾種細粒度鎖實現。
這裡我們還是接著用之前 [synchronize 關鍵字加鎖實現執行緒安全](http://mp.weixin.qq.com/s?__biz=MzUxNjgzODM1NQ==&mid=2247484311&idx=1&sn=78f3eeefc3cd25aff42ea85096b8fb07&chksm=f9a0052bced78c3d627f4c0643c38fe09d1650e9e6bdd0ae316107d75f0d67504395ceba9cba&scene=21#wechat_redirect) 文章中舉的賬戶扣款的例子好了,不過這裡為了更貼近系統的功能實現,我們換一下思路,功能實現不變,只是把錢轉換成我們系統中的使用的禮券好了,使用者每次在系統中購買某項功能需要支付一定的禮券。那既然要實現細粒度鎖,那就意味著不同使用者賬戶扣除禮券的操作互不影響,只需要保證相同賬戶下的禮券扣除操作是執行緒安全的即可,而且僅僅是扣除禮券的那一小部分的程式碼塊,對於賬戶的校驗我們可以接受併發執行。
### 分段鎖
我們先來想象這樣一個場景好了,可能我們的系統只有那麼一小部分的忠實使用者,他們更願意在我們的系統中通過禮券購買,從而使用一些特殊的功能,更多的使用者只是在使用我們系統的基本功能。接下來我們需要考慮這樣兩種情況:
- 同一使用者在同一時間通過禮券購買系統的付費功能,也就是在扣款時需要保證執行緒安全的情況
- 不同使用者在同一時間通過禮券購買系統的付費功能,這是系統的付費使用者併發量,這個和我們需要建立的細粒度鎖的數量有關。
基於上面我們描述的場景可以看出,對於第一種情況只要有禮券消費就可能存在,雖然不常出現但肯定存在,那麼我們就需要通過細粒度鎖來控制禮券的扣除操作。而第二種情況也是存在的,但是由於付費使用者的基數不是很大,所以這種情況也可以說很少了,這也就意味著在同一時間我們實際要建立的鎖的數量並不是很多。這裡稍微解釋一下,因為在禮券消費的時候我們肯定是要建立鎖來保證執行緒安全,而且鎖是和使用者繫結的,同一時間對於同一使用者只會建立一把鎖,而同一時間如果很多使用者都在消費禮券,那這一刻就是有多少使用者就需要建立多少把鎖了。
好了,通過上面的分析我們來看下分段鎖是如何實現細粒度鎖的。
```java
public class SegmentLock