ReentrantReadWriteLock
我有一些密切相关的问题在尝试使用来控制对具有许多不同读写操作的相当复杂的数据结构的访问时弹出。根据文档中的示例,我已经获取了一个读取和写入锁,并且我正在使用它们(据我所知)成功管理对该数据结构的并发访问。然而,在调试另一个问题时,我注意到有时我在同一个线程中获得了多个读锁。其基本原因是我有许多复杂的查询会调用更简单的查询(请参见下面的示例)。复杂的查询可以被认为是一个事务,即在和对ingetVersion()
的访问之间不应该有写操作。data
myQuery
. 这个当前的解决方案有效,但这意味着在代码中的某些地方,我将拥有同一个线程拥有的多个读锁。我注意到 write 等价物有一个isHeldByCurrentThread()
方法,但奇怪的是在readLock
. 我找不到以下内容:
- 在同一个线程中有多个读锁是不是很糟糕(糟糕的风格、性能或未来错误的风险)?
- is 不适合用于
WriteLock.isHeldByCurrentThread
检查错误(例如,期望写入锁但不存在,或者作为释放写入锁的条件)? - 如果这是一个问题,是否有最佳实践来决定如何进行?我是否将
lockedAquired
布尔值传递给可能从已经拥有锁的代码中调用的方法,我是否确保它们是唯一获取的,还是应该使用ReadLock.tryLock()
?
这是代码示例:
public class GraphWorldModel {
//unfair RW Lock (default, see javadoc)
protected final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
protected final ReentrantReadWriteLock.ReadLock readLock = rwl.readLock();
protected final ReentrantReadWriteLock.WriteLock writeLock = rwl.writeLock();
protected long versionID = 0;
protected Object data = null;
@Override
public long getVersion() {
long result = -1;
readLock.lock();
try {
result = this.versionID;
} finally {
readLock.unlock();
}
return result;
}
public ResultObject myQuery() {
//do some work
readLock.lock();
try {
long version = getVersion();
ResultObject result = new ResultObject(this.data, version);
//note: querying version and result should be atomic!
} finally {
readLock.unlock();
}
//do some more work
return result;
}
}