Java Wait and Notify: IllegalMonitorStateException
You can't wait()
on an object unless the current thread owns that object's monitor. To do that, you must synchronize
on it:
class Runner implements Runnable
{
public void run()
{
try
{
synchronized(Main.main) {
Main.main.wait();
}
} catch (InterruptedException e) {}
System.out.println("Runner away!");
}
}
The same rule applies to notify()
/notifyAll()
as well.
The Javadocs for wait()
mention this:
This method should only be called by a thread that is the owner of this object's monitor. See the
Throws:notify
method for a description of the ways in which a thread can become the owner of a monitor.
IllegalMonitorStateException
– if the current thread is not the owner of this object's monitor.
And from notify()
:
A thread becomes the owner of the object's monitor in one of three
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.
How to fix IllegalMonitorStateException when using wait and notify?
See the doc of wait
, notify
and notifyAll
:
Thorws IllegalMonitorStateException - if the current thread is not the
owner of the object's monitor.
That means you can not call them until you have aquired the monitor lock, in other words, until you have entered the synchronized block or synchronized method(check this for more).
Another important thing is, you should synchronize on the same object.
- When you use synchronized block with an explict object, you should call
wait
andnotify
on this object. - When you use synchronized method, you are implictly synchronizing on
this
, so you should callthis.wait()
andthis.notify()
(keywordthis
is not mandory).
In this case, you need create an Object
as monitor lock and share it between different classes.
Compliant example:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized (obj) {
... // Prepare the condition
obj.notifyAll();
}
Noncompliant example:
void waitMethod() {
wait(); // throws IllegalMonitorStateException
}
void notifyMethod() {
notify(); // throws IllegalMonitorStateException
}
Noncompliant example:
synchronized (obj1) {
while (<condition does not hold>)
obj1.wait();
... // Perform action appropriate to condition
}
synchronized (obj2) {
... // call notifyAll on obj2 will not stop the wait on obj1
obj2.notifyAll();
}
Noncompliant example:
in class1
synchronized void waitMethod() {
while(someCondition()) {
wait();
}
}
in class2
synchronized void notifyMethod() {
notify(); // call notifyAll on class2 will not stop the wait on class1
}
Java Lock Condition Wait and Notify: IllegalMonitorStateException
Note that Condition
as any class in Java extends Object
and hence it has the wait
method inherited from Object
, which I believe you calling by mistake here, the method that your meant to be calling to wait on a condition is Condition#await
rather than wait
.
Wait And Notify IllegalMonitorStateException Anonymous Class
On the first Thread, you call wait on an object while having its monitor (the object being this haveCoffee
).
However, on the second thread, you call notify()
on me
, while having the monitor of haveCoffee
.
This should work:
public class WaitAndNotify {
public static void main(String[] args) {
final Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
IllegalMonitorStateException on wait() call
You need to be in a synchronized
block in order for Object.wait()
to work.
Also, I recommend looking at the concurrency packages instead of the old school threading packages. They are safer and way easier to work with.
EDIT
I assumed you meant Object.wait()
as your exception is what happens when you try to gain access without holding the objects lock.
IllegalMonitorStateException notify() and wait()
you need to be the "owner of the object's monitor" to be able to call notify on it. so far your methods are all synchronized(this)
, yet they call notify() on other objects (that they are not synchronized on). in other words:
synchronized(t2) {
t2.notify();
}
and
synchronized(t1) {
t1.notify();
}
for a complete explanation of monitors and synchronization in java, see here, or look for similar questions here on SO, like this one - Java Wait and Notify: IllegalMonitorStateException
IllegalMonitorStateException on notify() when synchronized on an Integer
This
private static Integer state = 0;
is equivalent to
private static Integer state = Integer.valueOf(0);
The invocation of valueOf(0)
returns a reference to an Integer
object, call it A.
You then do
synchronized(state) {
your thread acquires the lock on the object referenced by state
, currently that is A.
You then do
state = 1;
which is equivalent to
state = Integer.valueOf(1);
which gives you a different reference to an Integer
object, call it B, and assigns it to state
. When you then call
state.notify();
you're invoking notify()
on an object, B, for which your thread doesn't own the monitor. You can't call notify
or wait
on objects for which your thread doesn't own the monitor.
How to use wait and notify in Java without IllegalMonitorStateException?
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
Related Topics
Only Using @JSONignore During Serialization, But Not Deserialization
Why Are Interface Variables Static and Final by Default
Rotating Coordinate Plane for Data and Text in Java
Java Socket Why Server Can Not Reply Client
How to Make a Java Thread Wait for Another Thread's Output
Best Way to Compare 2 Xml Documents in Java
Http Basic Authentication in Java Using Httpclient
Java: How to Test Methods That Call System.Exit()
Redirect to an External Url from Controller Action in Spring MVC
How to Use a Delimiter with Scanner.Usedelimiter in Java
Explicitly Calling a Default Method in Java
How to Handle Calendar Timezones Using Java
Unresponsive Keylistener for Jframe
Javafx Tableview Text Alignment
Java.Lang.Unsatisfiedlinkerror No *****.Dll in Java.Library.Path
Java: Check the Date Format of Current String Is According to Required Format or Not