简体   繁体   English

在Integer上同步时notify()上发生IllegalMonitorStateException

[英]IllegalMonitorStateException on notify() when synchronized on an Integer

I'm new to using wait() and notify() in Java and I'm getting an IllegalMonitorStateException. 我是在Java中使用wait()和notify()的新手,并且遇到了IllegalMonitorStateException。

Main Code 主要代号

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

        }

    }
}

I'm getting an IllegalMonitorStateException what state.notify() is called. 我收到一个IllegalMonitorStateException,称为state.notify()。 Any ideas? 有任何想法吗?

Edit : Based on answer below here is code that works. 编辑 :根据下面的答案是有效的代码。 As a side note, I was first trying this with an enum which has the same problem of using Integer. 附带说明一下,我首先尝试使用与使用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();
            }

        }

    }
}

This 这个

private static Integer state = 0;

is equivalent to 相当于

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

The invocation of valueOf(0) returns a reference to an Integer object, call it A. 调用valueOf(0)返回对Integer对象的引用,将其称为A。

You then do 然后你做

synchronized(state) {

your thread acquires the lock on the object referenced by state , currently that is A. 您的线程获取由state引用的对象的锁,当前为A。

You then do 然后你做

state = 1;

which is equivalent to 相当于

state = Integer.valueOf(1);

which gives you a different reference to an Integer object, call it B, and assigns it to state . 它为您提供了对Integer对象的不同引用,将其称为B并将其分配给state When you then call 当您再致电时

state.notify();

you're invoking notify() on an object, B, for which your thread doesn't own the monitor. 您正在对对象B调用notify() ,该对象的线程不拥有该监视器。 You can't call notify or wait on objects for which your thread doesn't own the monitor. 您不能调用notifywait线程不拥有监视器的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM