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

1 java illegalmonitorstateexcep notify wait

我刚接触在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();
            }

        }

    }
}
Run Code Online (Sandbox Code Playgroud)

我收到一个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();
            }

        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 7

这个

private static Integer state = 0;
Run Code Online (Sandbox Code Playgroud)

相当于

private static Integer state = Integer.valueOf(0);
Run Code Online (Sandbox Code Playgroud)

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

然后你这样做

synchronized(state) {
Run Code Online (Sandbox Code Playgroud)

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

然后你这样做

state = 1;
Run Code Online (Sandbox Code Playgroud)

这相当于

state = Integer.valueOf(1);
Run Code Online (Sandbox Code Playgroud)

它为您提供了对Integer对象的不同引用,将其称为B,并将其分配给state.然后你打电话

state.notify();
Run Code Online (Sandbox Code Playgroud)

你正在调用notify()一个对象B,你的线程不拥有该监视器.您不能调用notifywait在您的线程不拥有该监视器的对象上.