IllegalMonitorStateException on wait() call

后端 未结 10 1352
感动是毒
感动是毒 2020-11-22 11:37

I am using multi-threading in java for my program. I have run thread successfully but when I am using Thread.wait(), it is throwing java.lang.IllegalMonit

相关标签:
10条回答
  • 2020-11-22 12:05

    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.

    Happy coding.

    EDIT

    I assumed you meant Object.wait() as your exception is what happens when you try to gain access without holding the objects lock.

    0 讨论(0)
  • 2020-11-22 12:06

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

    0 讨论(0)
  • 2020-11-22 12:06

    In order to deal with the IllegalMonitorStateException, you must verify that all invocations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.

    Here is the simple example for to understand the concept of monitor

    public class SimpleMonitorState {
    
        public static void main(String args[]) throws InterruptedException {
    
            SimpleMonitorState t = new SimpleMonitorState();
            SimpleRunnable m = new SimpleRunnable(t);
            Thread t1 = new Thread(m);
            t1.start();
            t.call();
    
        }
    
        public void call() throws InterruptedException {
            synchronized (this) {
                wait();
                System.out.println("Single by Threads ");
            }
        }
    
    }
    
    class SimpleRunnable implements Runnable {
    
        SimpleMonitorState t;
    
        SimpleRunnable(SimpleMonitorState t) {
            this.t = t;
        }
    
        @Override
        public void run() {
    
            try {
                // Sleep
                Thread.sleep(10000);
                synchronized (this.t) {
                    this.t.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:13

    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.

    0 讨论(0)
提交回复
热议问题