notifyAll() number of invocations difference while profiling notifyAll() number of invocations difference while profiling multithreading multithreading

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():

  1. 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.

  2. 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, while Thread-0 just executes notifyAll().

  3. The example code provided is correctly programmed from a concurrent perspective and language perspective: wait() and notifyAll() are in synchronized methods to ensure control over the monitor; wait condition is within a while loop with the notifies correctly placed in the end of the methods. However, I noticed that the catch (InterruptedException e) block is empty, which means that if the thread that is waiting is interrupted, the notifyAll() method will be executed. This can be a cause for the several unexpected notifyAll().

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.