IllegalMonitorStateException的原因

时间:2013-10-04 04:39:07

标签: java multithreading

我收到以下代码的非法状态例外:

synchronized (this) {
        try {
        Thread.currentThread().wait();
        notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  }

我可以做的是同步“this”将捕获Monitor on Object调用方法,因为我在当前线程对象上调用wait而我真的没有锁定我得到错误。请验证我的理论。

4 个答案:

答案 0 :(得分:0)

你在当前线程上调用wait,在此调用它。

this.wait();

但是你永远不会得到notifyAll,因为没有线程进入同步块 可以达到notofyAll方法。他们都会先等待它。

我想你想让一个Thread等待另一个Thread做一些工作。

以下是线程之间同步如何工作的简短示例

public class ThreadTest {

    public static void main(String[] args) throws InterruptedException {
        Object monitor = new Object();
        Thread t1 = new Thread(new R1(monitor));
        Thread t2 = new Thread(new R2(monitor));

        t1.start();
        t2.start();

        t2.join();
        t1.join();
    }

    public static class R1 implements Runnable {

        private Object monitor;

        public R1(Object monitor) {
            this.monitor = monitor;
        }

        public void run() {
            System.out.println("R1 entered run");
            synchronized (monitor) {
                try {
                    monitor.wait();
                    System.out.println("R1 got monitor back");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static class R2 implements Runnable {

        private Object monitor;

        public R2(Object monitor) {
            this.monitor = monitor;
        }

        public void run() {
            System.out.println("R2 entered run");
            synchronized (monitor) {
                System.out.println("R2 will sleep for 1 sec");
                try {
                    Thread.sleep(1000);
                    System.out
                            .println("R2 will notify all threads waiting for monitor");
                    monitor.notifyAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

输出是:

R1 entered run
R2 entered run
R2 will sleep for 1 sec
R2 will notify all threads waiting for monitor
R1 got monitor back

答案 1 :(得分:0)

你已经获得了

的锁定
  

这个(当前对象)

你打电话给`

  

等待()

`当前线程就是为什么。

你应该在调用wait之前获取锁定,通知notifyAll

答案 2 :(得分:0)

案例1

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

情况2

...
synchronized(this){
   Thread.currentThread.wait();
}
...

案例1是明智的代码。它等待另一个线程在“notify[All]()”对象上调用this

案例2看起来很傻。它只能在当前线程和“this”是同一个对象时执行,或者您已经锁定了当前线程。否则,你会得到IllegalMonitorStateException。在Thread对象上进行同步是一件坏事,因为你无法确定还有什么可能在它们上同步。

顺便说一句,如果你想要做的只是在程序中暂停一段时间,你应该sleep(),而不是wait()

答案 3 :(得分:0)

来自Java doc for Object class wait()方法:

  

IllegalMonitorStateException - 如果当前线程不是所有者   对象的监视器。

在您的代码中,当前主题是this监视器的所有者,wait上调用了Thread.currentThread

Thread.currentThread().wait();替换为this.wait();