An IllegalMonitorStateException
is a runtime exception in Java that occurs in multithreaded applications. It indicates that the calling thread has attempted to wait on an object's monitor, or attempted to notify other threads waiting on an object's monitor, without owning the specified monitor.
Since the IllegalMonitorStateException
is an unchecked exception, it does not need to be declared in the throws
clause of a method or constructor.
 
What Causes IllegalMonitorStateException
When building multithreaded applications in Java, if a monitor needs to be synchronized on, the IllegalMonitorStateException
is thrown to indicate a thread attempted to wait or to notify other threads waiting on that monitor, without owning it.
Therefore, this exception occurs if one of the wait()
, notify()
or notifyAll()
methods of the Object
class are called outside a synchronized
block or method.
 
IllegalMonitorStateException Example
Here’s an example of an IllegalMonitorStateException
, thrown when the wait()
method is called outside a synchronized
block:
class MyRunnable implements Runnable {
public void run() {
try {
this.wait(100); // calling wait() without outside synchronized block
System.out.println("Thread in runnable state");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class IllegalMonitorStateExceptionExample {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
Since a thread must own a lock on the object’s monitor before calling the wait()
method, calling it outside a synchronized
block throws an IllegalMonitorStateException.
Running the above code throws the exception:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread is not owner
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:321)
at MyRunnable.run(IllegalMonitorStateExceptionExample.java:4)
at java.base/java.lang.Thread.run(Thread.java:832)
 
How to Resolve IllegalMonitorStateException
The IllegalMonitorStateException
can be resolved by calling the wait()
, notify()
and notifyAll()
methods after acquiring an object lock, i.e. within a synchronized
block or method.
The call to the wait()
method in the earlier example can be placed inside a synchronized
block to resolve the exception:
class MyRunnable implements Runnable {
public void run() {
synchronized (this) {
try {
this.wait(100);
System.out.println("Thread in runnable state");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class IllegalMonitorStateExceptionExample {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
Calling the wait()
method within a synchronized
block helps acquire a lock on the object monitor, which fixes the issue. Running the above code produces the correct output as expected:
Thread in runnable state
 
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!