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.
You're calling both wait
and notifyAll
without using a synchronized
block. In both cases the calling thread must own the lock on the monitor you call the method on.
From the docs for notify
(wait
and notifyAll
have similar documentation but refer to notify
for the fullest description):
This method should only be called by a thread that is the owner of this object's monitor. 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.
Only one thread at a time can own an object's monitor.
Only one thread will be able to actually exit wait
at a time after notifyAll
as they'll all have to acquire the same monitor again - but all will have been notified, so as soon as the first one then exits the synchronized block, the next will acquire the lock etc.