在Integer上同步时对notify()的IllegalMonitorStateException [英] IllegalMonitorStateException on notify() when synchronized on an Integer

查看:200
本文介绍了在Integer上同步时对notify()的IllegalMonitorStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始在Java中使用wait()和notify(),而且我遇到了IllegalMonitorStateException。

I'm new to using wait() and notify() in Java and I'm getting an 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()。有什么想法吗?

I'm getting an IllegalMonitorStateException what state.notify() is called. Any ideas?

编辑:根据下面的答案,这里有适用的代码。作为旁注,我首先尝试使用enum,它具有使用Integer的相同问题。

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.

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

        }

    }
}


推荐答案

private static Integer state = 0;

相当于

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

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

The invocation of valueOf(0) returns a reference to an Integer object, call it A.

然后你做

synchronized(state) {

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

your thread acquires the lock on the object referenced by state, currently that is A.

然后你做

state = 1;

相当于

state = Integer.valueOf(1);

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

which gives you a different reference to an Integer object, call it B, and assigns it to state. When you then call

state.notify();

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

you're invoking notify() on an object, B, for which your thread doesn't own the monitor. You can't call notify or wait on objects for which your thread doesn't own the monitor.

这篇关于在Integer上同步时对notify()的IllegalMonitorStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆