使用模式产生的原因如下:
如果条件不存在,我需要读取线程来等待数据。
读锁不支持条件,因此条件应从写锁中获取。
由于读线程会等待条件,因此它也应该获取写锁来等待。
我在类里面有以下锁定义:
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
protected final Lock readLock = rwl.readLock();
protected final Lock writeLock = rwl.writeLock();
protected final Condition hasData = writeLock.newCondition();
在我的编写方法中,我有以下模式:
try {
writeLock.lock();
//...
if( something_written ) {
hasData.signalAll();
}
}
finally {
writeLock.unlock();
}
在我的阅读方法中,我有以下模式
try {
readLock.lock();
while( data_absent ) {
// I need to acquire write lock to wait for condition!
try {
// first releasing read lock since we can't acquire write lock otherwise
// unfortunately this won't release a lock if it was acquired more than once (reentrant)
readLock.unlock();
// acquiring write lock to wait it's condition
writeLock.lock();
hasData.await(1000, TimeUnit.MILLISECONDS);
}
finally {
// releasing write lock back
writeLock.unlock();
// reacquiring read lock
// again see note about reentrancy
readLock.lock();
}
}
// reading
}
finally {
readLock.unlock();
}
上面的模式正确吗?
问题在于,如果 reader 是可重入的,即多次锁定读取,则释放代码将不起作用,并且 reader 会卡在获取写锁的行。
最佳答案
这听起来像是一个经典的生产者/消费者模式,因此我建议您为此目的查看现有的数据结构,例如 BlockingQueue 中的一个。实现。
生产者线程put()
将数据放入队列,消费者线程take()
将数据从队列中取出。
手动同步/锁定应该始终是最后的手段。
关于java - 从写入器向读取器发送信号时正确使用 ReentrantReadWriteLock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14279765/