Я реализовал простой профайлер с JVMTI для отображения вызова на wait()
и notifyAll()
. В качестве тестового примера я использую. пример использования производителя Oracle. У меня следующие три события:
- notifyAll() вызывается Вызывается
- wait()
- 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
, он может объяснить, почему этого не происходит с ожиданием.
Я забыл сказать, что я не запускал программы отдельно, оба журнала имеют одно и то же выполнение.
Дополнительная информация
Первоначально добавленный в качестве ответа, переместился на вопрос extraneon:
Я думаю, что я узнал, откуда some дополнительного 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
Но даже без этих внешних вызовов есть pleety notifyВсе звонки, которые не отображаются в отладке printf.