June 18, 2022

Why wait(), notify() and notifyAll() Methods Must be Called From a Synchronized Method or Block

Why wait(), notify() and notifyAll() methods in Java must be called from a synchronized method or block is asked quite frequently in Java interviews. Another question similar to this is Why wait(), notify() And notifyAll() Methods Are in Object Class. This post gives some of the points why it makes sense to call wait(), notify() and notifyAll() methods with in a synchronized context.

You need to be aware of the following two points-

1- As you must be knowing every object in Java has a single lock (also called monitor) associated with it. When a thread enters a synchronized method or synchronized block it acquires that lock. All other threads attempting to execute the same code (in synchronized method or synchronized block) have to wait for the first thread to finish and release the lock.

2- Description of wait(), notify() and notifyAll() methods-

  • wait- Causes the current thread owning the object's monitor lock to give up lock and go to waiting state.
  • notify- Wakes up a single thread that is waiting on this object's monitor.
  • notifyAll- Wakes up all threads that are waiting on this object's monitor.

Using these two points you just need to connect the dots to understand why wait(), notify() and notifyAll() methods in Java must be called from a synchronized method or block.

As clear from the description of the wait, notify and notifyAll methods these methods can only be called on an object when thread owns the object’s lock. Now, when does the thread own the object’s lock? When it has acquired it and entered the synchronized block or method. So, it is clear that you can call wait(), notify() and notifyAll() methods with in the synchronized context when the thread has the object’s lock.

Calling methods from outside the synchronized method or block

If you call wait, notify and notifyAll methods within a method that’s not synchronized, the program will compile, but when you run it you’ll get an IllegalMonitorStateException.

For example, in the following code wait() method is called out of the synchronized block, code will compile but at run time IllegalMonitorStateException will be thrown.

public void increment(){
  synchronized(this){
    for(int i = 1; i <= 5 ; i++){
      System.out.println(Thread.currentThread().getName() + " i - " + i);
    }
  }
  try {
    // calling wait method outside synchronized context
    this.wait();
  } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}
Output
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Unknown Source)
	at com.knpcode.Counter.increment(SynchronizedDemo.java:10)
	at com.knpcode.SynchronizedDemo$1.run(SynchronizedDemo.java:31)

That's all for the topic Why wait(), notify() and notifyAll() Methods Must be Called From a Synchronized Method or Block. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment