gpt4 book ai didi

java - 使用ReentrantReadWriteLock时是否需要降级锁

转载 作者:行者123 更新时间:2023-11-30 02:16:07 25 4
gpt4 key购买 nike

ReentrantReadWriteLock 的文档中有一个关于锁降级的示例用法(参见 this )。

class CachedData {
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
Object data;
volatile boolean cacheValid;

void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();//B
} finally {//A
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {//C
rwl.readLock().unlock();
}
}
}

如果我将对象数据更改为 volatile 对象数据,我是否还需要将写锁降级为读锁?

<小时/>

更新

我的意思是,如果我将 volatile 添加到data,在我释放注释A处的finally block 中的写锁之前,我是否还需要像注释BC处的代码那样获取读锁?或者代码可以利用 volatile 的优势?

最佳答案

不,无论您是否降级,都不需要 volatile (锁定已经保证了对数据的线程安全访问)。它也对原子性没有帮助,而原子性正是获取-读取-然后写入-锁定模式的作用(这也是问题的重点)。

您正在谈论需要降级,就像这是一件坏事一样。您可以保留写锁而不降级,一切都会正常进行。当读锁就足够时,您只是保持不必要的强锁。

您不需要降级为读锁,但如果不降级,您的代码效率会降低:如果 use(data) 需要 2 秒(很长一段时间) ,那么如果不进行锁定降级,每次刷新缓存时,您都会阻止所有其他读取器 2 秒。

如果您的意思是为什么在缓存刷新完成后甚至需要读锁,那是因为否则另一个线程可能会在我们“时启动新的缓存刷新(因为不会有任何锁)”我仍在处理use(data)

在给定的示例代码中,由于没有足够的信息,无法确定它是否真的重要,但它会为该方法创建一个可能的附加状态,这不是一个优势:

  • 一个或多个线程处于 use(data) 状态,具有读锁
  • 一个线程正在刷新缓存,有写锁
  • 一个线程处于没有锁的 use(data) 状态,一个线程正在使用写锁刷新缓存

关于java - 使用ReentrantReadWriteLock时是否需要降级锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48358411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com