我已經實現與JVMTI一個簡單的分析器對wait()
和notifyAll()
顯示的調用。作爲我正在使用的測試用例。 producer consumer example of Oracle。我有以下三個事件:notifyAll的()調用差的數量,同時仿形
- notifyAll的()被調用
- wait()的調用
- 等待()是左
的wait()
調用,當它離開它由異型使用事件MonitorEnter
和MonitorExit
。當名稱爲notifyAll
的方法退出時,將調用notifyAll()
調用。
現在我有以下的效果,首先是從探查本身和二是從Java,在那裏我已經把相應的System.out.println
聲明。
// Profiler:
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()
// Java:
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()
有人解釋了這種差異來自何處? notifyAll()
被稱爲很多次。有人告訴我這可能是由於Java對操作系統的請求產生誤報。
A notifyAll()
請求它發送到操作系統併發送誤報響應,看起來請求已成功。由於notifyAll
由分析方法調用而不是MonitorEnter
記錄,因此可以解釋爲什麼在等待時不會發生這種情況。
我忘了說,我沒有單獨運行程序,兩個日誌都來自同一個執行。
aditional的信息
最初加入作爲一個答案,移至提問extraneon:
我想我找到了在那裏附加notifyAll的一些是從哪裏來的,我加剖析其中notifyAll的調用該方法的上下文:
723519: Thread-1 invoked notifyAll() in Consumer.take
3763279: Thread-0 invoked notifyAll() in Producer.put
4799016: Thread-0 invoked notifyAll() in Producer.put
6744322: Thread-0 invoked notifyAll() in Producer.put
8450221: Thread-0 invoked notifyAll() in Producer.put
10108959: Thread-0 invoked notifyAll() in Producer.put
39278140: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
40725024: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
42003869: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
58448450: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
60236308: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
61601587: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
70489811: Thread-1 invoked notifyAll() in Consumer.take
75068409: Thread-1 invoked wait() in Drop.take
75726202: Thread-1 left wait() in Drop.take
77035733: Thread-1 invoked notifyAll() in Consumer.take
81264978: Thread-1 invoked notifyAll() in Consumer.take
85810491: Thread-1 invoked wait() in Drop.take
86477385: Thread-1 left wait() in Drop.take
87775126: Thread-1 invoked notifyAll() in Consumer.take
但即使沒有這些外部調用,有n的plteny otify所有不在printf調試中顯示的調用。
當你處理w /併發代碼時,使用system.out/err來跟蹤是一個可怕的想法。 Logging/System.out/err只是強加顯式同步+額外的緩存一致性。顯示導致問題的真實代碼,我會看看有什麼可能弄清楚。 – bestsss 2011-05-07 17:50:29
@bestsss我不是在談論顯示的事件順序,只是對notifyAll進行的調用總數。你的論點仍然存在嗎?真正的代碼如上所示,它是Oracle Java教程的一個例子。 – 2011-05-08 07:20:03
由於簡單的原因只有很多通知是正常的,並不是每個'notify'都會喚醒找到處於'wait'狀態的其他線程。添加追蹤可能會使問題惡化。我發現這種行爲完全正常。我使用CAS(比較和設置/交換)來避免輸入同步塊並廣泛地調用通知。 – bestsss 2011-05-08 12:44:46