在使用ReentrantReadWriteLock时,关于锁降级的一点疑问?
在查看ReentrantReadWriteLock的官方文档中看到了一个关于锁降级的例子代码:
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
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();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
}
这里,在释放写锁前需要先申请读锁,也既锁降级。具体原因是,如果不先获取读锁就释放写锁,那么在执行后面的use(data)
时,data
有可能被其它线程修改。而由于一个线程对于共享变量的修改对另一个线程来说是不可见的,所以会导致错误。这里,请问,如果我把data
变量用volatile
修饰,通过volatile
来保证可见性的话,是否还需要使用锁降级呢?不知道我对于volatile
保证可见性的理解是否正确?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里锁释放时,会把data刷会共享内存及主内存的。不存在可见性了吧 锁降级的主要目的应该还是在逻辑上。我觉得因为写读互斥,所以我们一直持有写锁的话,其他线程就无法读了,所以
我根本无法理解为什么要降级,你用写锁更新完了数据,别的线程同样需要进行写操作,自然锁释放后即可拿到,你又套了个读锁的意义在哪?。。。业务上有没有具体应用呢?
https://www.zhihu.com/questio...
他这里说的不可见是说在同一个线程中是没法感知其它线程对该变量进行的修改。
user(data),在当前线程中data为1,而在其他线程中被修改为2。虽然你通过增加volatile让当前线程知道了data被修改为2,但从程
序逻辑中你是没法判断它有没有被修改过,are you understand?锁降级的目的是保证在同一线程中数据的感知性,我觉得这里用可见性表达不准确。