我已经使用 JVMTI 实现了一个简单的分析器来显示在wait()
和上的调用notifyAll()
。作为测试用例,我正在使用。Oracle 的生产者消费者示例。我有以下三个事件:
- 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 对操作系统的请求的误报响应造成的。
它向操作系统发送了一个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
但是即使没有这些外部调用,也有很多 notifyAll 调用不会出现在 printf 调试中。