8

I do not understand why Java throw exception from subject in this code. Could somebody explain me it?

class Wait implements Runnable
{
    public void run() {
        synchronized (Object.class) {
            try {
                while(true) {
                    System.out.println("Before wait()");
                    wait();
                    System.out.println("After wait()");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ObjectMethodInConcurency 
{
    public static void main(String[] args) {
        Wait w = new Wait();
        (new Thread(w)).start();
    }
}
5
  • 3
    Read the javadoc for wait(). Commented Jan 15, 2014 at 22:01
  • 3
    @nos The current thread must own this object's monitor. and Throws:IllegalMonitorStateException - if the current thread is not the owner of the object's monitor. Commented Jan 15, 2014 at 22:06
  • 2
    You can only call wait() on an object which you have synchronized on. You are calling this.wait(), so instead of synchronized (Object.class), you must do synchronized (this). Object.class is not your object, it is a java.lang.Class object created by the Java runtime.
    – VGR
    Commented Jan 15, 2014 at 22:08
  • You are not calling notify() anywhere. Commented Jan 15, 2014 at 22:19
  • Thank you for information. I changed method call on Object.class.wait() and it works like I want.
    – koralgooll
    Commented Jan 16, 2014 at 0:09

1 Answer 1

18

Use synchronized (this) { instead of synchronized (Object.class) in your class

EDIT

Reasoning behind the IllegalMonitorException in above code

In Java using synchronized keyword is a way to create and obtain a monitor object which will be used as lock to execute corresponding code block.

In the above code that monitor is "Object.class".

And wait() method tells the current thread to wait until it is notifyed and you have to invoke wait() on the monitor object which owns the lock.

So the way to invoke wait() method is like below otherwise you will get IllegalMonitorException.

synchronized(monitor){
    monitor.wait();
}

So for your example you can either use "Object.class.wait()" or change the monitor to this since you are calling wait() method on the current instance

3
  • Because method call is on this. Method like wait, notify have to be invoke on synchronized object.
    – koralgooll
    Commented Jan 16, 2014 at 0:12
  • 1
    @Gray - Added my understanding about why it is giving IllegalMonitorException Commented Jan 16, 2014 at 6:40
  • 1
    You certainly did. Looks great. +1 One of the things to always realize with SO is that are you answering also for posterity.
    – Gray
    Commented Jan 16, 2014 at 13:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.