在Integer上同步时对notify()的IllegalMonitorStateException

时间:2014-09-08 21:56:08

标签: java wait notify illegalmonitorstateexcep

我在Java中使用wait()和notify()并且遇到IllegalMonitorStateException。

主要代码

public class ThreadTest {

    private static Integer state = 0;
    public static void main(String[] args) {

        synchronized(state) {
            System.out.println("Starting thread");

            Thread t = new Thread(new AnotherTest());
            t.start();

            synchronized(state) {
                state = 0;
                while(state == 0) {
                    try {
                        state.wait(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("State is: " + state);
            }
        }
    }   

    public static class AnotherTest implements Runnable {

        @Override
        public void run() {
            synchronized(state) {
                state = 1;
                state.notify();
            }

        }

    }
}

我收到了一个IllegalMonitorStateException,调用了state.notify()。有什么想法吗?

修改:根据以下答案,这里有适用的代码。作为旁注,我首先尝试使用枚举,这与使用Integer具有相同的问题。

public class ThreadTest {

    private static int state = 0;
    private static Object monitor = new Object();
    public static void main(String[] args) {

        synchronized(monitor) {
            System.out.println("Starting thread");

            Thread t = new Thread(new AnotherTest());
            t.start();

            state = 0;
            while(state == 0) {
                try {
                    for(int i = 0; i < 5; i++) {
                        System.out.println("Waiting " + (5 - i) + " Seconds");
                        Thread.sleep(1000);
                    }
                    monitor.wait(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println("State is: " + state);
        }
    }   

    public static class AnotherTest implements Runnable {

        @Override
        public void run() {
            synchronized(monitor) {
                state = 1;
                monitor.notify();
            }

        }

    }
}

1 个答案:

答案 0 :(得分:6)

这个

private static Integer state = 0;

相当于

private static Integer state = Integer.valueOf(0);

valueOf(0)的调用会返回对Integer对象的引用,称之为A.

然后你做

synchronized(state) {

你的线程获取state引用的对象的锁定,目前是A.

然后你做

state = 1;

相当于

state = Integer.valueOf(1);

为您提供对Integer对象的不同引用,将其称为B,并将其分配给state。当你打电话

state.notify();

您在对象B上调用notify(),您的线程并不拥有该监视器。您无法在线程未拥有监视器的对象上调用notifywait