I have implemented a simple profiler with JVMTI to display the invocation on wait()
and notifyAll()
. As a test case I am using the. producer consumer example of Oracle. I have the following three events:
- notifyAll() is invoked
- wait() is invoked
- wait() is left
The wait()
invocation and when its left it profiled by using the events MonitorEnter
and MonitorExit
. The notifyAll()
invocation is profiled when a method with name notifyAll
is exited.
Now I have the following results, the first is from the profiler itself and the second is from Java, where I have placed the appropriate System.out.println
statement.
// 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()
Has someone an explanation from what this discrepancy comes from? notifyAll()
is called so many times. I was told this might be due to false-positive responses from the request of Java to the operating system.
A notifyAll()
request it sent to the operating system and a false-positive response is sent, where it seems like the request was sucessfull. Since notifyAll
is logged by profiling method invocation instead of MonitorEnter
it could explain why this does not happen with wait.
I forgot to say, I didn't run the programs separately, both logs are from the same execution.
Aditional Information
Originally added as an answer, moved to the question by extraneon:
I think I found out where some of the additional notifyAll are coming from, I added the profiling of the method context in which notifyAll is called:
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
But even without these external calls, there are plteny of notifyAll calls which do not show up in the printf debugging.