Read Also: [Fixed] java.lang.IllegalStateException in Java
java.lang.IllegalMonitorStateException is an unchecked exception since it extends RuntimeException class. It was introduced in JDK (Java development kit) 1.0. The IllegalMonitorStateException class belongs to java.lang package instead of java.util.concurrent.* package.
[Fixed] java.lang.IllegalMonitorStateException in Java with Examples
As always, first, we will produce the java.lang.illegalMonitorStateException before moving on to the solution.1. Producing the exception by calling wait() or notify() or notifyAll() outside of a synchronized block
We can easily produce IllegalMonitorStateException by calling the wait() or notify() or notifyAll() method outside of a synchronized block as shown below in the example:
public class IllegalMonitorStateExceptionExample { public static void main(String args[]) { WaitingThread wt = new WaitingThread(); wt.start(); } } class WaitingThread extends Thread { public void run() { try { // Calling wait() method without having object lockthis.wait(1000); // throwing IllegalMonitorStateException} catch(InterruptedException ex) { ex.printStackTrace(); } System.out.println("Finished executing run() method"); } }
Output:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread is not owner
at java.base/java.lang.Object.wait(Native Method)
at WaitingThread.run(IllegalMonitorStateExceptionExample.java:16)
Explanation
wait(), notify(), and notifyAll() methods belongs to Object class in Java. A Thread should acquire the object's lock in order to call any of these methods on that object. If a Thread tries to call these methods on an object without acquiring the object's lock or outside of a synchronized block then the program will throw IllegalMonitorStateException as shown in the above example.
Solution
We can easily get rid of the java.lang.IllegalMonitorStateException by calling the wait(), notify(), or notifyAll() methods after acquiring the object's lock. In simple words, the program should call these methods inside a synchronized block only as shown below in the example.
public class IllegalMonitorStateExceptionExample { public static void main(String args[]) { WaitingThread wt = new WaitingThread(); wt.start(); } } class WaitingThread extends Thread { public void run() {synchronized(this)// Acquiring lock using the synchronized block{ try { // Calling wait() method inside synchronized block this.wait(1000); } catch(InterruptedException ex) { ex.printStackTrace(); } } System.out.println("Finished executing run() method"); } }
Output:
Finished executing run() method
2. Producing the exception by calling unlock() method of ReentrantLock's class
We can easily produce IllegalMonitorStateException by calling unlock() method of ReentrantLock's class as shown below in the example:
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.Lock; public class IllegalMonitorStateExceptionExample2 { public static void main(String args[]) { LockThread thread = new LockThread(); thread.start(); } } class LockThread extends Thread { public void run() { final Lock lock = new ReentrantLock();lock.unlock(); // raises IllegalMonitorStateExceptionSystem.out.println("Finished executing run() method of LockThread class"); } }
Output:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.base/java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:175)
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1007)
at java.base/java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:494)
at LockThread.run(IllegalMonitorStateExceptionExample2.java:18)
Explanation
According to Oracle docs, unlock() method of ReentrantLock's class attempts to release the lock. We are getting IllegalMonitorStateException in the above example because the current thread is not holding the lock and tries to release it by calling unlock() method.
Solution
We can easily get rid of the java.lang.IllegalMonitorStateException by calling lock() method before unlock() method on the current thread as shown below in the example.
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.Lock; public class IllegalMonitorStateExceptionExample2 { public static void main(String args[]) { LockThread thread = new LockThread(); thread.start(); } } class LockThread extends Thread { public void run() { final Lock lock = new ReentrantLock();lock.lock(); // Acquiring the locklock.unlock();// Releasing the lock System.out.println("Finished executing run() method of LockThread class"); } }
Output:
Finished executing run() method of LockThread class
That's all for today. Please mention in the comments if you have any questions related to how to fix java.lang.IllegalMonitorStateException in Java with examples.