Illegalmonitorstateexception on Wait() Call

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 and notify on this object.
  • When you use synchronized method, you are implictly synchronizing on this, so you should call this.wait() and this.notify()(keyword this 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 notify method for a description of the ways in which a thread can become the owner of a monitor.

Throws:

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



Leave a reply



Submit