最近,我阅读了The Art of Multiprocessor Programming第8章中关于使用signalAll()
Condition
对象的{{1>}的“监视器和阻止同步”的一些示例,没有获得与Condition
相关联的锁。
令人惊讶的是,我没有找到book’s errata中这些示例的任何修复。此外,他们建议对FifoReadWriteLock
的图8.12的示例进行更正,但是他们继续使用signalAll()
而没有锁定。这扰乱了我,我试图找到关于这些示例的其他注意事项,以了解这些Java示例以这种方式编写的原因。
例如,问题“answer”的How does a read-write mutex/lock work?显示了FifoReadWriteLock
的实现的相同示例,它将writeUnlock()
实现为:
void writeUnlock() {
writer = false;
condition.signalAll();
}
关于没有锁定获取,您可以阅读两个不同的原因:
答案 0 :(得分:1)
我不知道JDK中的任何Condition
实现允许在不拥有监视器的情况下等待或发送信号。
实际上,所有java.util.concurrent
类都依赖于AbstractQueuedSynchronizer
,它与内置监控方法wait()
/ notify()
/ notifyAll()
建立了相同的合同。它提供的条件变量,即它需要拥有内部锁,以便允许调用await()
/ signal()
/ signalAll()
。
如果您尝试使用建议的FifoReadWriteLock
的简单示例,您会发现它使用IllegalMonitorStateExceptions
方法提供了大量writeUnlock()
礼貌。如果您从其他方法应用lock-try-finally方法,这些异常将消失。
虽然确实拥有显示器并不是绝对需要等待或发出信号,但通常它是更好的方法,因为它可以避免您进行有条不紊的读取操作,它不应该像交接一样昂贵相同监视器的内部等待集之间仍然可以相当有效地完成,因为大多数情况下,您需要它来进行信令和调度,而不仅仅是信令。