Shivam Sinha
Shivam Sinha

Reputation: 5150

Wait And Notify IllegalMonitorStateException Anonymous Class

According to How to use wait and notify in Java? I have to synchronized on the same object to call notify.

I have synchronized on the same haveCoffee object. Why I am getting IllegalMonitorStateException when I call the notify method ?

I am Sleeping
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at com.example.concurrent.basic.WaitAndNotify$2.run(WaitAndNotify.java:42)

in the following code:

public class WaitAndNotify {

    public static void main(String[] args) {

        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);
                        notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        haveCoffee.start();
        me.start();
    }
}

Upvotes: 0

Views: 1487

Answers (3)

Ravindra babu
Ravindra babu

Reputation: 38950

From oracle documentation page,

public class IllegalMonitorStateException
extends RuntimeException

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

Whenever you get this exception, just go through your code and check wait() and notify() calls and the object on which these calls have been invoked. You can easily figure out what went wrong.

EDIT:

wait() or notify() calls have to be invoked on object once you get monitor on that object.

Upvotes: 1

You should be calling

haveCoffee.notify()

instead of just

notify().

If you invoke just notify() it calls the notify() method on the this object which is the second thread me where as you have synchronized on haveCoffee thread and that is the reason for exception you are seeing.

So the code in thread2 me should looks like:

synchronized (haveCoffee) {
    try {
        System.out.print("I am Sleeping");
        Thread.sleep(4000);
        haveCoffee.notify();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Upvotes: 0

Yoav Gur
Yoav Gur

Reputation: 1396

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

Upvotes: 2

Related Questions