If you try to synchronize your code with any other object that ThreadB , you will find that it never ends. This is due to the fact that there is a hidden call to notify .
Although I donβt know anywhere that this is indicated, Thread notifies itself when it ends. This is implied in the way the join method is implemented. This is the code for join :
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
(From JDK7 source code)
As you can see, wait calls make sense only if somewhere there is a notify call that is called after the stream ends. The same call to notify is what allows your program to terminate.
source share