notifyAll() number of invocations difference while profiling
I spent some time analyzing the Producer-Consumer example provided by Oracle and your output (profiler and Java program). There are some strange things on your outputs besides the several unexpected notifyAll()
:
we should expect the wait() method to execute 4 times (the
String
array manipulated by the producer has 4 elements). The result of your profiler shows that it only executedthree times.Another thing that is quite strange is the numbering of the threads in the output of the profiler. The example has two threads, however your profiler executes all the code in one thread, i.e.
Thread-1
, whileThread-0
just executesnotifyAll()
.The example code provided is correctly programmed from a concurrent perspective and language perspective:
wait()
andnotifyAll()
are in synchronized methods to ensure control over the monitor; wait condition is within awhile
loop with the notifies correctly placed in the end of the methods. However, I noticed that thecatch (InterruptedException e)
block is empty, which means that if the thread that is waiting is interrupted, thenotifyAll()
method will be executed. This can be a cause for the several unexpectednotifyAll()
.
In conclusion, without performing some modifications in the code and perform some extra tests, it won't be easy to figure out where the problem comes from.
As a side note, I'll leave this link Creating a Debugging and Profiling Agent with JVMTI for the curious ones that want to play with JVMTI.
If you have a race condition in your code, a profiler can slow down the code enough to either show or hide an error in your code. (I like to run my program in a profiler, just to show up race conditions.)
As notifyAll() will only notify wait()ing threads, calling wait() after the notifyAll() is likely to result in missing the notify. i.e. its stateless, it doesn't know you called notify before.
If you slow down your application the notifyAll() can be delayed until after the wait() starts.