Sotirios-Efstathios Maneas

About Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a postgraduate student at the Department of Informatics and Telecommunications of The National and Kapodistrian University of Athens. His main interests include distributed systems, web crawling, model checking, operating systems, programming languages and web applications.

java.lang.IllegalMonitorStateException – How to solve IllegalMonitorStateException

In this tutorial we will discuss about the IllegalMonitorStateException in Java. This exception, when thrown, indicates that the calling thread has attempted to wait on an object’s monitor, or has attempted to notify other threads that wait on an object’s monitor, without owning the specified monitor.

The IllegalMonitorStateException extends the RuntimeException class and thus, belongs to those exceptions that can be thrown during the operation of the Java Virtual Machine (JVM). It is an unchecked exception and thus, it does not need to be declared in a method’s or a constructor’s throws clause.

Finally, the IllegalMonitorStateException exists since the 1.0 version of Java.

The Structure of IllegalMonitorStateException

Constructors

  • IllegalMonitorStateException()
  • Creates an instance of the IllegalMonitorStateException class, setting null as its message.

  • IllegalMonitorStateException(String s)
  • Creates an instance of the IllegalMonitorStateException class, using the specified string as message. The string argument indicates the name of the class that threw the error.

The IllegalMonitorStateException in Java

As we have already described, the IllegalMonitorStateException indicates that the calling thread does not own the specified monitor. A thread can wait on a monitor after invoking the wait method. Moreover, a thread can notify one thread that waits on a monitor by invoking the notify method, or multiple threads by invoking the notifyAll method.

However, according to the description of the wait method, the calling thread must own the monitor. Furthermore, according to the corresponding descriptions, both notify and notifyAll methods should be called by a thread that is the owner of the object’s monitor.

A thread becomes the owner of an object’s monitor in one of the following ways:

  • By executing a synchronized instance method of that object.
  • By executing the body of a synchronized statement that synchronizes on the object.
  • For objects of type Class, by executing a synchronized static method of that class.

Notice that only one thread at a time can own an object’s monitor.

The following examples demonstrate two cases, where the calling thread does not own the mutex and still, invoke either the wait, or the notify method. First, we define a helper class:

HelperClass.java:

import java.util.concurrent.TimeUnit;

public class HelperClass {
	
	//The Object used for synchronization among threads.
	public final static Object obj = new Object();
	
	public static class WaitingThread extends Thread {
		
		@Override
		public void run() {
			synchronized (obj) {
				try {
					System.out.println("[WaitingThread]: Waiting for another thread "
									+ "to notify me...");
					obj.wait();
					System.out.println("[WaitingThread]: Successfully notified!");
				}
				catch (InterruptedException ex) {
					System.err.println("[WaitingThread]: An InterruptedException was caught: "
									+ ex.getMessage());
					ex.printStackTrace();
				}
			}
		}
	}
	
	public static class WakingThread extends Thread {
		@Override
		public void run() {
			synchronized (obj) {
				try {
					System.out.println("[WakingThread]: Sleeping for some time...");
					TimeUnit.SECONDS.sleep(5);
					System.out.println("[WakingThread]: Woke up!");
					
					System.out.println("[WakingThread]: About to notify another thread...");
					obj.notify();
					System.out.println("[WakingThread]: Successfully notified some other thread!");
				}
				catch (InterruptedException ex) {
					System.err.println("[WaitingThread]: An InterruptedException was caught: "
							+ ex.getMessage());
					ex.printStackTrace();
				}
			}
		}
	}
}

The HelperClass is used to define two execution threads, called WaitingThread and WakingThread respectively. An instance of the WaitingThread class blocks its execution by waiting to be notified by another thread. An instance of the WakingThread class sleeps for some amount of time and then, notifies a thread that is blocked on the synchronization object.

The following example demonstrates an execution, where the wait method is invoked by a thread that does not own the appropriate monitor:

IllegalMonitorStateWaitExample.java:

public class IllegalMonitorStateWaitExample {
	public static void main(String[] args) {
		try {
			//Try to wait on the synchronization object, without owning it.
			//The following statement results in an IllegalMonitorStateException.
			HelperClass.obj.wait();
		}
		catch (InterruptedException ex) {
			System.err.println("An InterruptedException was caught: " + ex.getMessage());
			ex.printStackTrace();
		}
	}
}

A sample execution is shown below:

Exception in thread "main" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at main.java.IllegalMonitorStateWaitExample.main(IllegalMonitorStateWaitExample.java:8)

The following example demonstrates an execution, where the notify method is invoked by a thread that does not own the appropriate monitor:

IllegalMonitorStateNotifyExample.java:

import java.util.concurrent.TimeUnit;
import main.java.HelperClass.WaitingThread;

public class IllegalMonitorStateNotifyExample {
	public static void main(String[] args) {
		try {
			Thread waitThread = new WaitingThread();
			
			//Start the execution.
			waitThread.start();
			
			//Sleep for some seconds.
			TimeUnit.SECONDS.sleep(5);
			
			//Try to notify the waiting thread without owning the synchronization object.
			//The following statement results in an IllegalMonitorStateException.
			HelperClass.obj.notify();
			
			//Wait for all threads to terminate.
			waitThread.join();
		}
		catch (InterruptedException ex) {
			System.err.println("An InterruptedException was caught: " + ex.getMessage());
			ex.printStackTrace();
		}
	}
}

A sample execution is shown below:

[WaitingThread]: Waiting for another thread to notify me...
Exception in thread "main" java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at main.java.IllegalMonitorStateNotifyExample.main(IllegalMonitorStateNotifyExample.java:19)

A proper example of execution, where the wait and notify methods are invoked only when the calling thread owns the monitor, is shown below:

RunningExample.java:

import main.java.HelperClass.WaitingThread;
import main.java.HelperClass.WakingThread;

public class RunningExample {
	public static void main(String[] args) {
		try {
			Thread waitThread = new WaitingThread();
			Thread wakingThread = new WakingThread();
			
			//Start the execution.
			waitThread.start();
			wakingThread.start();
			
			//Wait for all threads to terminate.
			waitThread.join();
			wakingThread.join();
		}
		catch (InterruptedException ex) {
			System.err.println("An InterruptedException was caught: " + ex.getMessage());
			ex.printStackTrace();
		}
	}
}

A sample execution is shown below:

[WaitingThread]: Waiting for another thread to notify me...
[WakingThread]: Sleeping for some time...
[WakingThread]: Woke up!
[WakingThread]: About to notify another thread...
[WakingThread]: Successfully notified some other thread!
[WaitingThread]: Successfully notified!

How to deal with the IllegalMonitorStateException

In order to deal with the IllegalMonitorStateException you must verify that all invokations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.

Download the Eclipse Project

This was a tutorial about the IllegalMonitorStateException in Java.

Download
You can download the full source code of this example here: IllegalMonitorStateExceptionExamples.zip.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.
Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close