Java Programming Tutorials

Java programming tutorials with many code examples!

Java IllegalMonitorStateException

java.lang.IllegalMonitorStateException form Object’s notify/wait methods indicates basic synchronization issue. In this post we’ll show the reason and how to fix it!

IllegalMonitorStateException from notify

The case occurs when you try to call Object.notify() or Object.notifyAll() from outside of synchronization block. In the following code we create an object that will be our lock, but we will not acquire it’s monitor using synchronized keyword and try to notify other threads waiting on this thread’s monitor to resume work:

System.out.println("In broken notify...");
Object lock = new Object();
try {
    lock.notify();
} catch (IllegalMonitorStateException e) {
    e.printStackTrace();
}

We don’t own lock object’s monitor so it throws exception:

In broken notify...
java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at com.farenda.java.lang.IllegalMonitorStateExceptionExample.brokenNotify(IllegalMonitorStateExceptionExample.java:17)
        at com.farenda.java.lang.IllegalMonitorStateExceptionExample.main(IllegalMonitorStateExceptionExample.java:7)

notify with object’s monitor

To fix the above case we have to obtain monitor for the lock using synchronized keyword:

Object lock = new Object();
synchronized (lock) {
    // now we can notify other threads:
    lock.notify();
}
System.out.println("Synchronized notify works!");

Now the exception is gone, because we’ve got lock’s monitor:

Synchronized notify works!

IllegalMonitorStateException from wait

The Object.wait() case is very similar to the problem with Object.notify(). Again we try to operate on lock without obtaining it’s monitor first:

System.out.println("In broken wait...");
Object lock = new Object();
try {
    lock.wait();
} catch (InterruptedException | IllegalMonitorStateException e) {
    e.printStackTrace();
}

And again the object’s monitor is in illegal state:

In broken wait...
java.lang.IllegalMonitorStateException
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:502)
        at com.farenda.java.lang.IllegalMonitorStateExceptionExample.brokenWait(IllegalMonitorStateExceptionExample.java:35)
        at com.farenda.java.lang.IllegalMonitorStateExceptionExample.main(IllegalMonitorStateExceptionExample.java:6)

Object.wait() with object’s monitor

Quick reminder how wait-notify work… Every object has an internal monitor that allows only one thread access the object. So if our thread wants to do any work with an object and prevent other threads from accessing it, we have to obtain this object’s monitor. This can be done, for instance, using synchronized keyword. When we have the monitor we can release it, allow other thread to do it’s job with the object (Object.wait() releases the monitor and… waits), hoping that the other thread will notify us after have completed it’s job (this is the purpose of notify and notifyAll methods). Now it should be clear that we have to obtain the monitor to be able to release it using lock.wait():

Object lock = new Object();
try {
    synchronized (lock) { // obtain lock's monitor
        // Release the lock, but wait only 500 ms for notify
        lock.wait(500);
    }
    System.out.println("Synchronized wait works!");
} catch (InterruptedException e) {
    e.printStackTrace();
}

Now the IllegalMonitorStateException is gone:

Synchronized wait works!

References:

Share with the World!