Working of Java wait method

194 views Asked by At

I have the following code:

   public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        ThreadImpl thr = new ThreadImpl();
        thr.start();
        Thread.sleep(1000);
        synchronized(thr){
            System.out.println( "MAIN "+thr.hashCode());
            System.out.println("Main -->got the lock");
            thr.wait();
            System.out.println("Main -->Done with waiting");
        }
    }
}

class ThreadImpl extends Thread{
    public synchronized void sayHello(){
        System.out.println("Ssay hello ");
    }
    @Override
    public void run() {
        synchronized(this){
            System.out.println( "METHOD "+this.hashCode());
            System.out.println("METHOD Got the lock ");
            System.out.println("METHOD Going for sleep ");
                for(int i =0;i< 100000;i++);
            try {
                Thread.sleep(2000);
                System.out.println("METHOD Woke up ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("METHOD Done leaving the thread");
        }
    }
}

In the main method of ThreadDemo, I am creating a thread object ThreadImpl and starting it. Next, the main thread sleeps for 1000ms. The run method of the thread will be executed in a separate thread.As part of this it loops 100000 times and sleeps for 2000ms. Then it exits the method. The main thread wakes up and acquires the lock for "thr" and then goes on wait state. As the other thread has completed its execution, this wait should be forever. However, I see the following result:

METHOD 1729414014
METHOD Got the lock
METHOD Going for sleep
METHOD Woke up
METHOD Done leaving the thread
MAIN 1729414014
Main -->got the lock
Main -->Done with waiting

How is it that the main method continues its execution when no one has notified it?

1

There are 1 answers

1
xingbin On

This is spurious wake-up, see jls:

The thread may be removed from the wait set due to any one of the following actions, and will resume sometime afterward:

  • A notify action being performed on m in which t is selected for removal from the wait set.
  • A notifyAll action being performed on m.
  • An interrupt action being performed on t.
  • If this is a timed wait, an internal action removing t from m's wait set that occurs after at least millisecs milliseconds plus nanosecs nanoseconds elapse since the beginning of this wait action.
  • An internal action by the implementation. Implementations are permitted, although not encouraged, to perform "spurious wake-ups", that is, to remove threads from wait sets and thus enable resumption without explicit instructions to do so.