How to Fix Java.Lang.IllegalMonitorStateException

Sheeraz Gul Feb 02, 2024
How to Fix Java.Lang.IllegalMonitorStateException

The IllegalMonitorStateException is related to multithreading programming. This tutorial describes and demonstrates the IllegalMonitorStateException in Java.

the java.lang.IllegalMonitorStateException in Java

The IllegalMonitorStateException occurs when working with multithreading programming in Java. When we synchronize on a monitor, and a thread tries to wait or notify the other threads waiting on the monitor without owning it that time, the IllegalMonitorStateException occurs.

If we call the methods wait(), notify(), or notifyAll() from the object class, which is not in the synchronized block, this exception will be thrown. Let’s try an example in this scenario.

package delftstack;

class DemoClass implements Runnable {
  public void run() {
    try {
      // The wait method is called outside the synchronized block
      this.wait(100);
      System.out.println("Thread can successfully run.");
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
  }
}

public class Example {
  public static void main(String[] args) {
    DemoClass DemoRunnable = new DemoClass();
    Thread DemoThread = new Thread(DemoRunnable);
    DemoThread.start();
  }
}

The code above creates a class that implements the Runnable class and then calls the wait method outside the synchronized block. The Example creates a thread from the instance of DemoClass.

It will throw the IllegalMonitorStateException because the wait method is called outside the synchronized block, and the thread must own a lock on the monitor before we call the wait() method. See output:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread is not owner
    at java.base/java.lang.Object.wait(Native Method)
    at delftstack.DemoClass.run(Example.java:7)
    at java.base/java.lang.Thread.run(Thread.java:833)

To fix this exception, we must call the wait(), notify(), or notifyAll() methods after the object lock is acquired, which will be in the synchronized block.

Now let’s put the wait() method into the synchronized block, then make the above code error-free. See example:

package delftstack;

class DemoClass implements Runnable {
  public void run() {
    synchronized (this) {
      try {
        // The wait method is called outside the synchronized block
        this.wait(100);
        System.out.println("Thread can successfully run.");
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
    }
  }
}

public class Example {
  public static void main(String[] args) {
    DemoClass DemoRunnable = new DemoClass();
    Thread DemoThread = new Thread(DemoRunnable);
    DemoThread.start();
  }
}

Now the wait() method is inside the synchronized block, and the lock on the object monitor is acquired, the code will run successfully. See output:

Thread can successfully run.
Author: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook

Related Article - Java Exception