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();
}
}
}
如果我将Object data
更改为volatile Object data
,我是否还需要降级写锁定才能读锁定?
更新
我的意思是如果我将volatile
添加到data
,在finally
块中发布注释A
的写锁之前,我是否还需要获取读取内容锁定为评论B
和C
的代码吗?或者代码可以利用volatile
?
答案 0 :(得分:2)
不,无论你是否降级都不需要date_create TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
(锁定已经保证了对volatile
的线程安全访问)。
您正在谈论需要降级,这是一件坏事。你可以保持写锁定而不是降级,事情就可以了。当读锁定就足够时,你只是保持一个不必要的强锁。
您不需要降级到读取锁定,但如果您不这样做会降低您的代码效率:如果data
需要2秒(很长一段时间) ,然后在没有锁定降级的情况下,每次刷新缓存时都会阻止所有其他读取器2秒钟。
如果你的意思是为什么在缓存刷新完成后你甚至需要读锁定,那么因为否则另一个线程可能会启动一个新的缓存刷新(因为它不会是我们仍然在use(data)
上工作。
在给定的示例代码中,由于没有足够的信息,它无法确定它是否真正重要,但它会为该方法创建一个可能的附加状态,而不是优势:
use(data)
,具有读锁use(data)
中没有锁定,一个线程正在使用写锁定刷新缓存