Search code examples
javamultithreadingwaitsynchronizednotify

Does a thread waked after wait() and got the monitor again continues from the next instruction after wait() or from the beginning?


Suppose a thread_1 does this:

synchronized(o) {
    dosomthing1;
    o.wait();
    dosomthing2;
}

Suppose thread_1 was awakened, blocked on getting o monitor, got it. What will be the next thread_1 instruction? dosomthing1 or dosomthing2?


Solution

  • Let's suppose we have 2 methods printFirst() will print from 0 to 5 and printSecond() will print from 0 to 10

    void printFirst() {
        for (int i = 0; i <= 5; i++) {
            System.out.print(i + " ");
        }
    }
    
    void printSecond() {
        for (int i = 0; i <= 10; i++) {
            System.out.print(i + " ");
        }
    }
    

    These two methods are going to used by Thread-0 as you can see first in the try catch first it will call printFirst method after the method has finished its work wait() method will put the current on WAIT STATE and any code below the wait() will not be executed until notify is invoked.

    synchronized void testThreadWait(){
        System.out.println(Thread.currentThread().getName() +" starting to work");
        try {
            printFirst();
            wait();
            System.out.println(Thread.currentThread().getName() + "starts");
            printSecond();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    The other method will be executed from Thread-1 and it will print something and it will notify() the thread that is in current wait state

    synchronized void testThreadNotify(){
        System.out.println("\n" + Thread.currentThread().getName() + "starting to work");
        System.out.println("Thread one is waiting");
        System.out.println("Preparing to notify Thread One");
        notify();
    }
    

    When wait() method is invoked Thread-0 will continue to do his job in this case will call printSecond() the method that was below the wait() method , and it will print numbers from 0-10

    Full code

    class TestThread{
    
        void printFirst() {
            for (int i = 0; i <= 5; i++) {
                System.out.print(i + " ");
            }
        }
    
        void printSecond() {
            for (int i = 0; i <= 10; i++) {
                System.out.print(i + " ");
            }
        }
    
        synchronized void testThreadWait(){
            System.out.println(Thread.currentThread().getName() +" starting to work");
            try {
                printFirst();
                wait();
                System.out.println(Thread.currentThread().getName() + "starts");
                printSecond();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("This will be printed after wait");
        }
    
        synchronized void testThreadNotify(){
            System.out.println(Thread.currentThread().getName() + "starting to work");
            System.out.println("Thread one is waiting");
            System.out.println("Preparing to notify Thread One");
            notify();
        }
    }
    
    public class Test{
        public static void main(String args[]){
            final TestThread c=new TestThread();
            new Thread(){
                public void run(){c.testThreadWait();}
            }.start();
            new Thread(){
                public void run(){c.testThreadNotify();}
            }.start();
        }
    }
    

    OUTPUT

    Thread-0 starting to work
    0 1 2 3 4 5 
    Thread-1starting to work
    Thread one is waiting
    Preparing to notify Thread One
    Thread-0starts
    0 1 2 3 4 5 6 7 8 9 10 <--- prints only printSecond()
    

    Here you can see that when Thread-0 is being notified it is printing only the second method that was below the wait() method