java併發編程-StampedLock高性能讀寫鎖

一、讀寫鎖

在我的《java併發編程》上一篇文章中爲大家介紹了《ReentrantLock讀寫鎖》,ReentrantReadWriteLock可以保證最多同時有一個線程在寫數據,或者可以同時有多個線程讀數據,但讀寫不能同時進行。

比如你正在做的是日誌,有一個線程正在做寫操作,但是在寫日誌的時候你可能需要把日誌集中轉移到集中管理日誌服務,但是此時讀線程不能讀數據(因爲無法獲取讀鎖)。面對這個需求,ReentrantReadWriteLock顯然不是我們的解決方案,我們希望:最多一個線程在進行寫操作(加寫鎖),但是同時允許多個線程進行讀操作(加讀鎖),解決方案是StampedLock。

二、悲觀讀鎖

StampedLock 同樣可以實現寫鎖和讀鎖的功能,Stamped在英文中有印章的含義,對於StampedLock大家可以這麼理解,使用一個印章加鎖,必須使用該印章解鎖。

public class TestStampedLock {
    Map<String,String> map = new HashMap<>();
    //鎖對象
    private StampedLock lock = new StampedLock();
 
    //寫操作函數
    public void put(String key, String value){
        long stamp = lock.writeLock(); //加寫鎖
        try {
            map.put(key, value); //寫操作
        } finally {
            lock.unlockWrite(stamp);  //釋放寫鎖
        }
    }
 
    public String get(String key) {
        long stamp = lock.readLock(); //加讀鎖
        try {
            return map.get(key); //讀操作
        } finally {
            lock.unlockRead(stamp); //釋放讀鎖
        }
    }
}

上文中的讀鎖readLock,在StampedLock模式中被稱爲悲觀讀鎖,之所以叫做悲觀讀鎖是和StampedLock支持的另一種模式“樂觀讀”相對應的。
寫鎖、悲觀讀鎖的語義和 ReadWriteLock 的寫鎖、讀鎖的語義基本是一致的,允許多個線程同時獲取悲觀讀鎖,但是隻允許一個線程獲取寫鎖,寫鎖和悲觀讀鎖是互斥的。多線程環境下,寫操作的同時不能讀。所以到這裏爲止,StampedLock與ReadWriteLock並沒有很大的區別。

三、樂觀讀

需要注意的是,這裏我寫的是樂觀讀,而不是樂觀讀鎖,因爲樂觀讀是不加鎖的。通過tryOptimisticRead()函數獲取一個stamp,這裏的tryOptimisticRead() 就是樂觀讀,樂觀讀因爲沒有加鎖,所以讀取數據的性能會更高一點。即:已經有寫操作線程加鎖的同時,仍然允許讀操作線程繼續進行。

如果你的讀寫操作有比較強的時間點數據一致性要求,即:同一個時間點讀操作讀到的數據,一定與該時間點寫操作保持數據一致性。那麼,你就需要進行validate校驗,stamp此時可以理解爲一個版本號,如果寫操作版本爲2,讀操作版本爲1,說明你讀到的數據不是最新的。你需要去讀取最新版本的數據(版本號爲2),所以需要升級爲悲觀讀鎖,代碼如下:

public String readWithOptimisticLock(String key) {
    long stamp = lock.tryOptimisticRead(); //樂觀讀
    String value = map.get(key); //讀取數據
 
    if(!lock.validate(stamp)) {  //校驗數據是否是最新版本
        stamp = lock.readLock();  //如果不是,升級爲悲觀讀鎖
        try {
            return map.get(key);
        } finally {
            lock.unlock(stamp);               
        }
    }
    return value;
}

歡迎關注我的博客,更多精品知識合集

本文轉載註明出處(必須帶連接,不能只轉文字):字母哥博客 - zimug.com

覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力!。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章