偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:什么鎖比讀寫(xiě)鎖性能更高?

開(kāi)發(fā) 前端
使用樂(lè)觀讀鎖的特性可以提高讀操作的并發(fā)性能,適用于讀多寫(xiě)少的場(chǎng)景。如果樂(lè)觀讀鎖獲取后,在讀取共享變量前發(fā)生了寫(xiě)入操作,則 validate 方法會(huì)返回 false,此時(shí)需要轉(zhuǎn)換為悲觀讀鎖或?qū)戞i重新訪問(wèn)共享變量。

在并發(fā)編程中,讀寫(xiě)鎖 ReentrantReadWriteLock 的性能已經(jīng)算是比較高的了,因?yàn)樗鼘⒈^鎖的粒度分的更細(xì),在它里面有讀鎖和寫(xiě)鎖,當(dāng)所有操作為讀操作時(shí),并發(fā)線程是可以共享讀鎖同時(shí)運(yùn)行的,這樣就無(wú)需排隊(duì)執(zhí)行了,所以執(zhí)行效率也就更高。

那么問(wèn)題來(lái)了,有沒(méi)有比讀寫(xiě)鎖 ReentrantReadWriteLock 性能更高的鎖呢?

答案是有的,在 Java 中,比 ReentrantReadWriteLock 性能更高的鎖有以下兩種:

  • 樂(lè)觀鎖:樂(lè)觀鎖是一種非阻塞鎖機(jī)制,它是通過(guò) Compare-And-Swap(CAS)對(duì)比并替換來(lái)進(jìn)行數(shù)據(jù)的更改的,它假設(shè)多個(gè)線程(或進(jìn)程)之間很少會(huì)發(fā)生沖突,因此不會(huì)加鎖,只有在需要修改之后,通過(guò)對(duì)比并替換來(lái)修改共享變量的值,因此它在非高并發(fā)的環(huán)境下的性能是非常高的。
  • StampedLock:它是 JDK 8 中新增的鎖類(lèi)型,它提供了三種鎖模式:讀鎖、寫(xiě)鎖和樂(lè)觀讀鎖。相較于 ReentrantReadWriteLock,StampedLock 提供了更細(xì)粒度的控制,支持樂(lè)觀讀取操作,可以提高并發(fā)性能。

1.樂(lè)觀鎖

樂(lè)觀鎖在 Java 中最常見(jiàn)的實(shí)現(xiàn)就是 atomic 家族下的類(lèi),例如 AtomicInteger、AtomicLong 等,它的核心方法中使用了 CAS 對(duì)比并替換進(jìn)行變量的修改操作,如下源碼所示:

public final int incrementAndGet() {
    return U.getAndAddInt(this, VALUE, 1) + 1;
}
public final int getAndAddInt(Object o, long offset, int delta) {
    int v;
    do {
        v = getIntVolatile(o, offset);
    } while (!weakCompareAndSetInt(o, offset, v, v + delta)); // CAS 方法
    return v;
}

然而,如果是高并發(fā)環(huán)境下,那么樂(lè)觀鎖可以需要通過(guò)多次自旋才能成功修改變量的數(shù)據(jù),這種場(chǎng)景下,樂(lè)觀鎖的性能可能就不如 ReentrantReadWriteLock 了。

2.StampedLock

StampedLock 有三種讀寫(xiě)方法:

  • readLock:讀鎖,用于多線程并發(fā)讀取共享資源。
  • writeLock:寫(xiě)鎖,用于獨(dú)占寫(xiě)入共享資源。
  • tryOptimisticRead:讀樂(lè)觀鎖,用于在不阻塞其他線程的情況下嘗試讀取共享資源。

其中 readLock() 和 writeLock() 方法與 ReentrantReadWriteLock 的用法類(lèi)似,而 tryOptimisticRead() 方法則是 StampedLock 引入的新方法,它用于非常短的讀操作。

因此,我們?cè)诩渔i時(shí),可以使用性能更高的讀樂(lè)觀鎖來(lái)替代傳統(tǒng)的讀鎖,如果能加鎖成功,則它可以和其他線程(即使是寫(xiě)操作)一起執(zhí)行,也無(wú)需排隊(duì)運(yùn)行(傳統(tǒng)讀鎖遇到寫(xiě)鎖時(shí)需要排隊(duì)執(zhí)行),這樣的話 StampedLock 的執(zhí)行效率就會(huì)更高,它是使用如下:

// 創(chuàng)建 StampedLock 實(shí)例
StampedLock lock = new StampedLock();
// 獲取樂(lè)觀讀鎖
long stamp = lock.tryOptimisticRead(); 
// 讀取共享變量
if (!lock.validate(stamp)) { // 檢查樂(lè)觀讀鎖是否有效
    stamp = lock.readLock(); // 如果樂(lè)觀讀鎖無(wú)效,則獲取悲觀讀鎖
    try {
        // 重新讀取共享變量
    } finally {
        lock.unlockRead(stamp); // 釋放悲觀讀鎖
    }
}

// 獲取悲觀讀鎖
long stamp = lock.readLock(); 
try {
    // 讀取共享變量
} finally {
    lock.unlockRead(stamp); // 釋放悲觀讀鎖
}

// 獲取寫(xiě)鎖
long stamp = lock.writeLock(); 
try {
    // 寫(xiě)入共享變量
} finally {
    lock.unlockWrite(stamp); // 釋放寫(xiě)鎖
}

使用樂(lè)觀讀鎖的特性可以提高讀操作的并發(fā)性能,適用于讀多寫(xiě)少的場(chǎng)景。如果樂(lè)觀讀鎖獲取后,在讀取共享變量前發(fā)生了寫(xiě)入操作,則 validate 方法會(huì)返回 false,此時(shí)需要轉(zhuǎn)換為悲觀讀鎖或?qū)戞i重新訪問(wèn)共享變量。

課后思考

StampedLock 底層是如何實(shí)現(xiàn)的?

責(zé)任編輯:姜華 來(lái)源: 磊哥和Java
相關(guān)推薦

2024-05-15 09:41:22

樂(lè)觀鎖編程

2024-06-11 00:01:00

并發(fā)validate場(chǎng)景

2024-08-12 17:36:54

2020-09-16 07:56:28

多線程讀寫(xiě)鎖悲觀鎖

2022-07-04 08:06:14

Go語(yǔ)言互斥鎖

2021-09-01 07:21:41

面試官開(kāi)發(fā)讀寫(xiě)鎖

2025-10-31 02:00:00

2023-02-08 08:32:41

輪詢鎖

2021-12-16 18:38:13

面試Synchronize

2024-01-11 08:12:20

重量級(jí)監(jiān)視器

2025-10-14 02:22:00

2021-08-20 07:54:20

非公平鎖 Java多線編程

2022-06-27 08:07:13

Go語(yǔ)言互斥鎖

2021-01-21 07:53:29

面試官Promis打印e

2024-10-10 09:40:29

2024-09-24 16:30:46

分布式鎖Redis數(shù)據(jù)中間件

2022-08-11 18:27:50

面試Redis分布式鎖

2025-07-22 01:33:00

分布式Zookeeper

2023-10-13 00:00:00

并發(fā)樂(lè)觀鎖CAS

2024-01-29 01:08:01

悲觀鎖遞歸鎖讀寫(xiě)鎖
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)