How to Use Wait and Notify in Java Without Illegalmonitorstateexception

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();
}

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
}

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();
}
}

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.

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();
}

wait() and notify() method , always IllegalMonitorStateException is happen and tell me current Thread is not Owner Why?

You need to hold the lock on the object you want to wait on (you can only call it within a synchronized block).

Also, calling wait on a Thread is very unusual and probably not what you want.

I am not sure what you are trying to do, but could you be confusing wait with sleep?

If you want to wait for another thread to finish, that would be anotherThread.join().

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.

Notify exception java.lang.IllegalMonitorStateException Locks

You are calling wait and notify on explicit lock objects and that is not legal. If you are using explicit lock objects, you have to use Condition object associated with it. Then you should call condition.await and condition.signalAll methods instead of wait and notify. Here's the idiom for using explicit locks in your particular scenario.

final Condition setA = lock.newCondition();
public void threadA() {
lock.lock();
try {
while (a == 5)
setA.await();
System.out.println("A = " + a);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}

public void threadB() {
lock.lock();
try {
this.a = 11;
System.out.println("B = " + a);
setA.signalAll();
} finally {
lock.unlock();
}
}

And this program produces the following output:

B = 11
A = 11


Related Topics



Leave a reply



Submit