Correctly, this does not guarantee which thread will be executed first. Thread b can make its notification before the main thread ever starts to wait.
In addition to this, the thread may return from waiting without being notified, so setting the flag and checking it before entering the expected is technically insufficient. You can rewrite it to something like
public class ThreadA { public static void main(String[] args) throws InterruptedException { ThreadB b = new ThreadB(); b.start(); synchronized(b){ while (!b.isDone()) { System.out.println("Waiting for b to complete..."); b.wait(); } System.out.println("Total is: " + b.total); } } } class ThreadB extends Thread { int total; private boolean done = false; @Override public void run(){ synchronized(this){ for(int i=0; i<100 ; i++){ total += i; } done = true; notify(); } } public boolean isDone() {return done;} }
so the main thread will wait for b to be executed with its calculation, regardless of who starts over.
By the way, the API documentation recommends not synchronizing threads. JDK synchronizes threads to implement Thread # join. The thread that completes sends a notification that everything that joins it receives. If you triggered a notification or notified about it from the thread on which you acquired the lock, then joining it may return earlier. One of the side effects here is that if you delete the notification, the code works the same.
Nathan hughes
source share