You are not doing anything wrong with calling a method, but you have a condition.
Although in an ideal world the main thread will reach its synchronized block after all worker threads have reached the wait () call, there is no guarantee of this (you explicitly told the virtual machine that you do not want the threads to execute sequentially with the main thread, creating threads for it) . It may happen (for example, if you have only one core) that the thread scheduler decides to block all worker threads immediately to start the main thread. Workflows may have been disabled in context due to a cache miss. Perhaps one worker thread blocks I / O (the print statement), and the main thread switches to its place.
Thus, if the main thread manages to reach the synchronized block before all the worker threads have reached the wait () call, then those worker threads that have not reached the wait () call will not work as intended. Since the current setup does not allow you to control this, you must add an explicit reference to this. You can either add some kind of variable that increases, since each worker thread reaches wait (), and the main thread does not call notifyAll () until this variable reaches 5, or you can have the main thread loop and call notifyAll again ( ) so that worker threads are freed up in several groups.
Look in the java.util.concurrent package - there are several lock classes that provide more powerful features than basic synchronized locks. More than ever, Java saves you from re-creating the wheel. CountDownLatch seems especially relevant.
Therefore, concurrency is difficult. You have to design to make sure everything still works when threads are executed in requests that you don't need, as well as orders that you would like.
Scott
source share