摘要:一起來聊聊這個在高并發(fā)環(huán)境下比ReadWriteLock更快的鎖——StampedLock。
本文分享自華為云社區(qū)《【高并發(fā)】一文徹底理解并發(fā)編程中非常重要的票據(jù)鎖——StampedLock》,作者: 冰 河 。
在勐海等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計 網(wǎng)站設(shè)計制作定制開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè),勐海網(wǎng)站建設(shè)費用合理。
ReadWriteLock鎖允許多個線程同時讀取共享變量,但是在讀取共享變量的時候,不允許另外的線程多共享變量進(jìn)行寫操作,更多的適合于讀多寫少的環(huán)境中。那么,在讀多寫少的環(huán)境中,有沒有一種比ReadWriteLock更快的鎖呢?
答案當(dāng)然是有!那就是我們今天要介紹的主角——JDK1.8中新增的StampedLock!沒錯,就是它!
StampedLock與ReadWriteLock相比,在讀的過程中也允許后面的一個線程獲取寫鎖對共享變量進(jìn)行寫操作,為了避免讀取的數(shù)據(jù)不一致,使用StampedLock讀取共享變量時,需要對共享變量進(jìn)行是否有寫入的檢驗操作,并且這種讀是一種樂觀讀。
總之,StampedLock是一種在讀取共享變量的過程中,允許后面的一個線程獲取寫鎖對共享變量進(jìn)行寫操作,使用樂觀讀避免數(shù)據(jù)不一致的問題,并且在讀多寫少的高并發(fā)環(huán)境下,比ReadWriteLock更快的一種鎖。
這里,我們可以簡單對比下StampedLock與ReadWriteLock,ReadWriteLock支持兩種鎖模式:一種是讀鎖,另一種是寫鎖,并且ReadWriteLock允許多個線程同時讀共享變量,在讀時,不允許寫,在寫時,不允許讀,讀和寫是互斥的,所以,ReadWriteLock中的讀鎖,更多的是指悲觀讀鎖。
StampedLock支持三種鎖模式:寫鎖、讀鎖(這里的讀鎖指的是悲觀讀鎖)和樂觀讀(很多資料和書籍寫的是樂觀讀鎖,這里我個人覺得更準(zhǔn)確的是樂觀讀,為啥呢?我們繼續(xù)往下看啊)。其中,寫鎖和讀鎖與ReadWriteLock中的語義類似,允許多個線程同時獲取讀鎖,但是只允許一個線程獲取寫鎖,寫鎖和讀鎖也是互斥的。
另一個與ReadWriteLock不同的地方在于:StampedLock在獲取讀鎖或者寫鎖成功后,都會返回一個Long類型的變量,之后在釋放鎖時,需要傳入這個Long類型的變量。例如,下面的偽代碼所示的邏輯演示了StampedLock如何獲取鎖和釋放鎖。
public class StampedLockDemo{ //創(chuàng)建StampedLock鎖對象 public StampedLock stampedLock = new StampedLock(); //獲取、釋放讀鎖 public void testGetAndReleaseReadLock(){ long stamp = stampedLock.readLock(); try{ //執(zhí)行獲取讀鎖后的業(yè)務(wù)邏輯 }finally{ //釋放鎖 stampedLock.unlockRead(stamp); } } //獲取、釋放寫鎖 public void testGetAndReleaseWriteLock(){ long stamp = stampedLock.writeLock(); try{ //執(zhí)行獲取寫鎖后的業(yè)務(wù)邏輯。 }finally{ //釋放鎖 stampedLock.unlockWrite(stamp); } } }