1

我是在 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() 被调用。有任何想法吗?

编辑:根据下面的答案,这里是有效的代码。作为旁注,我首先尝试使用与使用整数有相同问题的枚举。

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();
            }

        }

    }
}
4

1 回答 1

8

这个

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();

您正在调用notify()一个对象 B,您的线程不拥有该对象的监视器。您不能调用notify或调用wait线程不拥有监视器的对象。

于 2014-09-08T22:06:40.500 回答