它必须是关于技术作者必须在您复制相关文章之前呈现的技巧。我不确定你正在阅读哪本书,但我会试着回答这个问题。
我读过一本类似的书“Thinking in Java”,讲述了相同的竞争条件。它表明可以使用wait和notify来阻止这种情况,以便代码不会错过通知信号。
当使用notify()/ wait()或notifyAll( )/ wait()来协调两个线程时,可能会错过信号。假定T1是一个线程 通知T2,并且该两个线程使用 以下(有缺陷的)的方式实施:
T1:
synchronized(sharedMonitor) {
<setup condition for T2>
sharedMonitor.notify();
}
T2:
while(someCondition) {
// Assume that T2 evaluates someCondition and finds
// it true, now when program goes to next line thread
// scheduler switches to T1 and executes notify again
// after when control comes to T2 it blindly executes
// wait(), but it has already missed notify so it will
// always be waiting.
.... some code ....
synchronized(sharedMonitor) {
sharedMonitor.wait();
}
}
(T2的设置条件)是防止T2调用wait()(如果还没有)的动作。
解决方案是通过someCondition变量来防止竞争条件。下面是T2正确的做法:
synchronized(sharedMonitor) {
while(someCondition) {
sharedMonitor.wait();
}
}
我不认为答案是有的,在我的问题的反例的原因。 – croraf
这里没有反例。您的wait()调用位于同步块中。 – EJP
其根本原因是内存模型的工作方式 - 您可以查看:http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.2详细说明等待集如何工作。 – assylias