wait()
とで呼び出しを表示するために、JVMTI を使用して単純なプロファイラーを実装しましたnotifyAll()
。テストケースとして、私はを使用しています。Oracle の生産者消費者の例。次の 3 つのイベントがあります。
- notifyAll() が呼び出されます
- wait() が呼び出される
- wait() が残っている
wait()
イベントMonitorEnter
とMonitorExit
. _ 名前を持つメソッドが終了すると、notifyAll()
呼び出しがプロファイリングされますnotifyAll
。
これで、次の結果が得られました。1 つ目はプロファイラー自体からのもので、2 つ目は適切なステートメントを配置した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 の要求からオペレーティング システムへの誤検知応答が原因である可能性があると言われました。
オペレーティング システムに送信されたnotifyAll()
要求と、要求が成功したように見える偽陽性の応答が送信されます。notifyAll
代わりにプロファイリング メソッド呼び出しによってログに記録されるためMonitorEnter
、これが待機で発生しない理由を説明できます。
言い忘れましたが、プログラムを個別に実行したわけではありません。両方のログは同じ実行からのものです。
追加情報
元は回答として追加されていましたが、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
しかし、これらの外部呼び出しがなくても、printf デバッグに表示されない notifyAll 呼び出しがたくさんあります。