的使用模式由以下原因產生:正確使用ReentrantReadWriteLock時,從寫入者到讀者的信號?
我需要讀線程等待數據,如果它不存在與條件。
讀鎖不支持條件,所以條件應該從寫鎖中獲取。
既然讀線程會等待條件,它也應該等待寫鎖。
我在課堂以下鎖定義:
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();
}
是t他的模式正確嗎?
問題是,如果讀者是可重入的,即鎖定讀取不止一次,那麼釋放代碼不起作用,讀者掛在獲取寫鎖定的行。
短短的意見......你錯過了'試穿finally'構建嵌套的鎖定/解鎖。按照慣例,你應該在'try'塊之外「鎖定」。 – mre
爲什麼你獲得'readlock',而你已經獲得了'writelock'(反之亦然)?這不是使用它們的正確方法。看看在[API](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReadWriteLock.html) –
順便說一句,如果可能的話,我建議使用一個用於解決您的問題的Java併發'隊列'(看起來像一個典型的生產者/消費者問題)。 –