when java.lang.IllegalMonitorStateException is thrown in java

What is hierarchy of java.lang.IllegalMonitorStateException?

-java.lang.Object
-java.lang.Throwable
 -java.lang.Exception
  -java.lang.RuntimeException
   -java.lang.IllegalMonitorStateException



IllegalMonitorStateException is Checked (compile time exceptions) and UnChecked (RuntimeExceptions) in java ?

java.lang.IllegalMonitorStateException is a RuntimeExceptions in java.



What is IllegalMonitorStateException in java?


Before calling Wait(), notify() and notifyAll() methods thread must own lock on object’s monitor, means wait(), notify() and notifyAll() methods must be called either from synchronized blocks or synchronized method otherwise IllegalMonitorStateException is thrown at runtime.


Scenarios where IllegalMonitorStateException may be thrown in java>

  1. Before calling Wait() method thread must own lock on object’s monitor , means wait() method must be called either from synchronized blocks or synchronized method otherwise IllegalMonitorStateException is thrown at runtime.
Example -
class MyRunnable implements Runnable {
public void run() {
     System.out.println("MyRunnable,in run() method");
     try {
          this.wait(1000); // calling wait() without acquiring object lock
                            // throws IllegalMonitorStateException
     } catch (InterruptedException e) {
          e.printStackTrace();
     }
     System.out.println("Thread in runnable state after 1000 millisecs");
}
}
public class IllegalMonitorStateExceptionExampleUsingWait  {
public static void main(String[] args) {
     MyRunnable myRunnable=new MyRunnable();
     Thread thread1=new Thread(myRunnable,"Thread-1");
     thread1.start();
}
}
/*OUTPUT
MyRunnable,in run() method
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at MyRunnable.run(IllegalMonitorStateExceptionExampleUsingWait.java:5)
at java.lang.Thread.run(Unknown Source)
*/

Solution - call wait() by acquiring object lock i.e from synchronized block.

Example -
class MyRunnable implements Runnable {
public void run() {
     synchronized (this) {
          System.out.println("MyRunnable,in run() method");
          try {
              this.wait(1000); // calling wait() by acquiring object lock doesn't
                                 // throws IllegalMonitorStateException
              System.out
                       .println("Thread in runnable state after 1000 millisecs");
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
     }
}
}
public class AvoidIllegalMonitorStateExceptionExampleUsingWait  {
public static void main(String[] args) {
     MyRunnable myRunnable=new MyRunnable();
     Thread thread1=new Thread(myRunnable,"Thread-1");
     thread1.start();
}
}
/*OUTPUT
MyRunnable,in run() method
Thread in runnable state after 1000 millisecs
*/



  1. Likewise, before calling notify() and notifyAll() methods thread must own lock on object’s monitor, means notify() and notifyAll() methods must be called either from synchronized blocks or synchronized method otherwise IllegalMonitorStateException is thrown at runtime.

  1. ReEntrantLock’s unlock() method can throw IllegalMonitorStateException -

If the current thread is not holding the lock and calls unlock() method then IllegalMonitorStateException is thrown.
Example -
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class IllegalMonitorStateExceptionExampleUsingLock {
    public static void main(String[] args) {
     final Lock lock = new ReentrantLock();
     new Thread(new Runnable() {
          public void run() {
              System.out.println("Thread-1 is Waiting to acquire lock");
              //lock.lock();
             
              lock.unlock(); // It will throw IllegalMonitorStateException
          }
     }, "Thread-1") {
     }.start();
}
}
/*OUTPUT
Exception in thread "Thread-1" Thread-1 is Waiting to acquire lock
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
at java.util.concurrent.locks.ReentrantLock.unlock(Unknown Source)
at IllegalMonitorStateExceptionExampleUsingLock$1.run(AvoidIllegalMonitorStateExceptionExampleUsingLock.java:14)
at java.lang.Thread.run(Unknown Source)
*/


Solution - call lock() method before calling unlock() method on the current thread and IllegalMonitorStateException is not thrown.
Example -
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class AvoidIllegalMonitorStateExceptionExampleUsingLock {
public static void main(String[] args) {
     final Lock lock = new ReentrantLock();
     new Thread(new Runnable() {
          public void run() {
              System.out.println("Thread-1 is Waiting to acquire lock");
              lock.lock();
             
              System.out.println("Thread-1 has acquired lock.");
             
              lock.unlock();
             
              System.out.println("Thread-1 has released lock.");
          }
     }, "Thread-1") {
     }.start();
}
}
/*OUTPUT
Thread-1 is Waiting to acquire lock
Thread-1 has acquired lock.
Thread-1 is about to release lock.
*/


  1. ReEntrantLock’s  newCondition() method can throw IllegalMonitorStateException -

Method returns a Condition instance to be used with this Lock instance.
Condition instance are similar to using Wait(), notify() and notifyAll() methods.

IllegalMonitorStateException is thrown if this lock is not held when any of the Condition waiting or signalling methods are called.


eEdit
Must read for you :