Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IllegalMonitorStateException on wait() call

People also ask

Which exception is thrown by Wait method?

The IllegalMonitorStateException is related to multithreading programming in Java. If we have a monitor we want to synchronize on, this exception is thrown to indicate that a thread tried to wait or to notify other threads waiting on that monitor, without owning it.

What is wait () in Java?

Simply put, wait() is an instance method that's used for thread synchronization. It can be called on any object, as it's defined right on java. lang. Object, but it can only be called from a synchronized block. It releases the lock on the object so that another thread can jump in and acquire a lock.

How do you use wait and notify in Java?

The wait() Method Simply put, calling wait() forces the current thread to wait until some other thread invokes notify() or notifyAll() on the same object. For this, the current thread must own the object's monitor.

How does notifyAll work in Java?

notifyAll() wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods. The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.


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.


wait is defined in Object, and not it Thread. The monitor on Thread is a little unpredictable.

Although all Java objects have monitors, it is generally better to have a dedicated lock:

private final Object lock = new Object();

You can get slightly easier to read diagnostics, at a small memory cost (about 2K per process) by using a named class:

private static final class Lock { }
private final Object lock = new Lock();

In order to wait or notify/notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you will need a while loop to check for the wakeup condition (find a good text on threading to explain why).

synchronized (lock) {
    while (!isWakeupNeeded()) {
        lock.wait();
    }
}

To notify:

synchronized (lock) {
    makeWakeupNeeded();
    lock.notifyAll();
}

It is well worth getting to understand both Java language and java.util.concurrent.locks locks (and java.util.concurrent.atomic) when getting into multithreading. But use java.util.concurrent data structures whenever you can.


I know this thread is almost 2 years old but still need to close this since I also came to this Q/A session with same issue...

Please read this definition of illegalMonitorException again and again...

IllegalMonitorException is 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.

This line again and again says, IllegalMonitorException comes when one of the 2 situation occurs....

1> wait on an object's monitor without owning the specified monitor.

2> notify other threads waiting on an object's monitor without owning the specified monitor.

Some might have got their answers... who all doesn't, then please check 2 statements....

synchronized (object)

object.wait()

If both object are same... then no illegalMonitorException can come.

Now again read the IllegalMonitorException definition and you wont forget it again...


Based on your comments it sounds like you are doing something like this:

Thread thread = new Thread(new Runnable(){
    public void run() { // do stuff }});

thread.start();
...
thread.wait();

There are three problems.

  1. As others have said, obj.wait() can only be called if the current thread holds the primitive lock / mutex for obj. If the current thread does not hold the lock, you get the exception you are seeing.

  2. The thread.wait() call does not do what you seem to be expecting it to do. Specifically, thread.wait() does not cause the nominated thread to wait. Rather it causes the current thread to wait until some other thread calls thread.notify() or thread.notifyAll().

    There is actually no safe way to force a Thread instance to pause if it doesn't want to. (The nearest that Java has to this is the deprecated Thread.suspend() method, but that method is inherently unsafe, as is explained in the Javadoc.)

    If you want the newly started Thread to pause, the best way to do it is to create a CountdownLatch instance and have the thread call await() on the latch to pause itself. The main thread would then call countDown() on the latch to let the paused thread continue.

  3. Orthogonal to the previous points, using a Thread object as a lock / mutex may cause problems. For example, the javadoc for Thread::join says:

    This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.