java.util.concurrent.locks.ReentrantReadWriteLock 的文档
免责声明:我不太擅长 Java,只是比较 C# 和 Java 之间的读/写锁,以更好地理解这个主题&两种实施背后的决策。
有关于ReentrantReadWriteLock的JavaDoc< /a>.它规定了以下有关锁升级/降级的内容:
- 锁降级 ...但是,从读锁升级到写锁是不可能的。
它还具有以下内容显示从读锁手动升级到写锁的示例:
// Here is a code sketch showing how to exploit reentrancy
// to perform lock downgrading after updating a cache
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// upgrade lock manually
#1: rwl.readLock().unlock(); // must unlock first to obtain writelock
#2: rwl.writeLock().lock();
if (!cacheValid) { // recheck
...
}
...
}
use(data);
rwl.readLock().unlock();
这是否意味着实际上上面的示例在某些情况下可能无法正确运行 - 我的意思是在第 1 行和第 1 行之间没有锁。 #2 底层结构会受到其他线程的更改。所以它不能被认为是升级锁的正确方法,还是我在这里错过了什么?
Disclaimer: I'm not very good at Java and just comparing read/writer locks between C# and Java to understand this topic better & decisions behind both implementations.
There is JavaDoc about ReentrantReadWriteLock. It states the following about upgrade/downgrade for locks:
- Lock downgrading ... However, upgrading from a read lock to the write lock is not possible.
It also has the following example that shows manual upgrade from read lock to write lock:
// Here is a code sketch showing how to exploit reentrancy
// to perform lock downgrading after updating a cache
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// upgrade lock manually
#1: rwl.readLock().unlock(); // must unlock first to obtain writelock
#2: rwl.writeLock().lock();
if (!cacheValid) { // recheck
...
}
...
}
use(data);
rwl.readLock().unlock();
Does it mean that actually the sample from above may not behave correctly in some cases - I mean there is no lock between lines #1 & #2 and underlying structure is exposed to changes from other threads. So it can not be considered as the correct way to upgrade the lock or do I miss something here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的你是对的。但是这段代码通过在获取写锁后再次调用
if (!cacheValid) { // recheck
来处理这种情况。Yes, you are right. But this code handles the situation by calling
if (!cacheValid) { // recheck
again after it acquired the write lock.