wait - notify example in Java..

from this book, which I like a lot!

This is the example from the book, just with a little modifications..

ThreadB.java
package biz.tugay.crazythreads;
 
public class ThreadB extends Thread {
 
    int total;
 
    @Override
    public void run() {
        synchronized (this) {
            System.out.println("================================");
            System.out.println("ThreadB entered synchronized block.");
            for (int i = 0; i < 10; i++) {
                total = total + i;
            }
            System.out.println("ThreadB is about to notify..");
            notify();
            System.out.println("ThreadB did notify, will sleep for a second..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {}
            System.out.println("ThreadB is done sleeping..");
            System.out.println("================================");
        }
    }
}

TestClass.java
package biz.tugay.crazythreads;
 
public class TestClass {
 
    public static void main(String[] args) {
        final ThreadB threadB = new ThreadB();
        threadB.start();
 
        synchronized (threadB) {
            System.out.println("Main thread entered synchronized block!");
            try {
                System.out.println("Main thread will start waiting now.");
                threadB.wait();
                System.out.println("Main thread is done waiting..");
                System.out.println("Total is: " + threadB.total);
            } catch (InterruptedException e) {
                System.out.println("Oopps!");
            }
        }
    }
}

and the output will be...
Main thread entered synchronized block!
Main thread will start waiting now.
================================
ThreadB entered synchronized block.
ThreadB is about to notify..
ThreadB did notify, will sleep for a second..
ThreadB is done sleeping..
================================
Main thread is done waiting..
Total is: 45

So What?

It seems like every time I run this program, it gives me the same result.. But I still think there is some danger in this code. I am not sure, but I think it is not guranteed that the main thread will acquire the lock on object threadB first. Let 's modify the TestClass a little, and add the following code snippet..
// existing code..
threadB.start();
 
try {
    Thread.sleep(1000);
} catch (InterruptedException ignored) {}
 
synchronized (threadB) {
// existing code..

and the output will be..
================================
ThreadB entered synchronized block.
ThreadB is about to notify..
ThreadB did notify, will sleep for a second..
ThreadB is done sleeping..
================================
Main thread entered synchronized block!
Main thread will start waiting now.

What are you talking about?

Well I guess if ThreadB gets the lock before the main thread, main thread will just wait forever, isn 't it?