它必須是關於技術作者必須在您複製相關文章之前呈現的技巧。我不確定你正在閱讀哪本書,但我會試着回答這個問題。
我讀過一本類似的書「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