gpt4 book ai didi

java - 为什么在 ReentrantReadWriteLock 中,readLock() 应该在 writeLock().lock() 之前解锁?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:40:34 26 4
gpt4 key购买 nike

来自ReentrantReadWriteLock class javadoc :

void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
5: rwl.readLock().unlock();
6: rwl.writeLock().lock();
// 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
14: rwl.readLock().lock();
15: rwl.writeLock().unlock(); // Unlock write, still hold read
}

use(data);
rwl.readLock().unlock();
}

为什么要像评论里写的那样在获取写锁之前先释放读锁?如果当前线程持有读锁,那么应该允许在其他线程不再读取时获取写锁,而不管当前线程是否也持有读锁。这是我所期望的行为。

我希望在 ReentrantReadWriteLock 类内部完成第 5 行和第 6 行的锁升级以及第 14 行和第 15 行的锁降级。为什么这不可能?

换句话说,我希望代码能像这样正常工作:

void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// The readlock is upgraded to writeLock when other threads
// release their readlocks.
rwl.writeLock().lock();
// no need to recheck: other threads can't have acquired
// the write lock since this thread still holds also the readLock!!!
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.writeLock().unlock(); // Unlock write, still hold read
}

use(data);
rwl.readLock().unlock();
}

这看起来是一种更好、更安全的处理锁定的方法,不是吗?

有人可以解释这个奇怪的实现的原因吗?谢谢。

最佳答案

将读锁升级为写锁的问题是,如果两个线程同时尝试这样做,可能会导致死锁。考虑以下顺序:

  1. 线程A:获取读锁
  2. 线程 B:获取读锁(请注意,两个线程现在共享读锁)。
  3. 线程 A:尝试获取写锁(当线程 B 持有读锁时阻塞)
  4. 线程 B:尝试获取写锁(当线程 A 持有读锁时阻塞)

现在有一个僵局。线程 A 或 B 都无法继续,也永远不会释放读锁。

关于java - 为什么在 ReentrantReadWriteLock 中,readLock() 应该在 writeLock().lock() 之前解锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16901640/

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