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.
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 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.
reason of IllegalMonitorStateException if I use wait within sync block
You are synchronizing on monitor
, so you should wait()
on monitor, too:
monitor.wait();
Right now you are waiting on this
, which is not the owner of the monitor because synchronization is on monitor
.
Note that of course the notify
should also be done on the monitor
object, and that you might want to consider using notify
/notifyAll
in both threads. Otherwise it may happen that one thread starves waiting for a missing notification. Using a timeout (the overloaded version of wait
) might also be a good idea to catch corner cases.
java.lang.IllegalMonitorStateException when condition.wait
That's because you're calling the wrong method. You should call await()
rather than wait()
on a Condition
object:
reentrantLock.lock();
try {
condition.await();
} finally {
reentrantLock.unlock();
}
You're currently calling wait
which is the Object.wait()
method, which requires you to be synchronized on the object that you are calling it on. But that's not what you want, you want the specific wait functionality of the Condition
class, and that is only available through the method await
.
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();
}
}
Related Topics
Java.Sql.Sqlexception: - Ora-01000: Maximum Open Cursors Exceeded
Java Array, Finding Duplicates
How to Find Files That Match a Wildcard String in Java
Javafx Fxml Controller - Constructor VS Initialize Method
Java - Method Name Collision in Interface Implementation
Why Must Local Variables, Including Primitives, Always Be Initialized in Java
Avoid Jackson Serialization on Non Fetched Lazy Objects
Regex for Matching Something If It Is Not Preceded by Something Else
Jquery, Spring MVC @Requestbody and JSON - Making It Work Together
How to Convert Comma-Separated String to List
Closing Database Connections in Java
Why Integer Class Caching Values in the Range -128 to 127
How to Set the Default Locale in the Jvm
How to Deploy a Javafx 11 Desktop Application with a Jre
How Will Java Lambda Functions Be Compiled