wait(), notify() And notifyAll() Methods in Java

The wait(), notify() and notifyAll() methods in Java are used for inter-thread communication. The object whose lock is held is used for the communication among the threads.

There are two important points about the wait(), notify() and notifyAll() methods in Java-

1- These methods are implemented in Object class as final methods. Since Object class is super class of all the classes in Java so wait(), notify() and notifyAll() methods are available in all the classes.

wait(), notify() and notifyAll() methods in Object class are declared as below-

  • public final void wait() throws InterruptedException
  • public final void notify()
  • public final void notifyAll()

Refer Why wait(), notify() And notifyAll() Methods Are in Object Class to know the reason for putting these methods in Object class.

2- wait(), notify() and notifyAll() methods must be called within a synchronized method or block. If you call these methods within a method that’s not synchronized, the program will compile, but when you run it IllegalMonitorStateException will be thrown.

Refer Why wait(), notify() and notifyAll() Methods Must be Called From a Synchronized Method or Block to know the reason why these methods are to be called with ina synchronized context.

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

Output

Also you can call wait(), notify() and notifyAll() methods on the object whose lock has been used to enter the synchronized context. If you use any other object then also code will compile but IllegalMonitorStateException will be thrown at run time.

wait() method

wait() method causes the current thread to place itself into waiting state. Here current thread means the thread currently executing with in the synchronized context and owns this object’s monitor lock.

wait() method in the Object class is overloaded and has three variants.

  • final void wait()– Causes the current thread to wait until another thread calls notify or notifyAll method or the thread is interrupted.
  • final void wait(long timeout)– Causes the current thread to wait until another thread calls notify or notifyAll method, the thread is interrupted or the maximum time to wait (in milliseconds) has expired.
  • final void wait(long timeout, int nanos)– Causes the current thread to wait until another thread calls notify or notifyAll method, the thread is interrupted or the maximum time to wait (in milliseconds) plus additional time in nanoseconds has expired.

notify() method

Wakes up a single thread that is waiting on this object’s monitor. If there are more than one thread waiting on this object any one of them is arbitrarily chosen to be awakened.

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. If any other threads are trying to acquire the lock on this object to enter the synchronized method or block then the awakened thread also compete with them in usual manner with no special advantage or any disadvantage.

notifyAll() method

Wakes up all threads that are waiting on this object’s monitor rather than a single thread. The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. Again these awakened threads have to compete with any other threads trying to acquire lock on this object.

Spurious wakeup

In very rare cases a waiting thread can wake up without being notified, interrupted, or timing out this is known as spurious wakeup. Applications must guard against it by putting a call to wait() within a loop that checks the condition on which the thread is waiting.

Reference- https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#wait(long,int)

Java wait, notify, notifyAll example

A very good example to show wait(), notify() And notifyAll() methods in practice is implementing a producer consumer using two threads. Here producer thread will produce a message and put it in a list, during that period consumer thread should wait. Once there is a message in a list consumer thread should be notified. Same way producer thread should be in waiting state when consumer thread is consuming the message and should be notified to put another message in the list when the current message is consumed. List object is the shared object here on which wait and notify methods should be called.

Output

If you don’t use wait() and notify() methods here for inter thread communication and just synchronize on the shared object, still only one of the thread will acquire the lock but nothing stops the thread to execute more than once after entering the synchronized block. You can run the same example by commenting the code for wait and notify methods.

Output

As you can see here, consumer thread tries to get another message from the list after consuming one message as nothing stops it to keep executing once it is in the synchronized block. This results in IndexOutOfBoundsException as list is already empty.

That’s all for the topic wait(), notify() And notifyAll() Methods in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

One Comment

  1. Pingback: isAlive() And join() Methods in Java - KnpCode

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.