当前位置: 首页 > 面试题库 >

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

贺彬
2023-03-14
问题内容

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

        }

    }
}

问题答案:

这个

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,该对象的线程不拥有监视器。您不能调用notifywait线程不拥有监视器的对象上进行调用。



 类似资料:
  • 问题内容: 为什么此测试程序会导致? 结果: 问题答案: 您已经正确地指出了必须从同步块中调用。 但是,在您的情况下,由于自动装箱,您在其上同步的对象与您在其上调用的实例不同。实际上,新的,递增的实例仍然被限制在堆栈中,并且其他线程可能不会在调用中被阻塞。 您可以实现自己的可变计数器来执行同步。根据您的应用程序,您可能还会发现AtomicInteger满足您的需求。

  • 问题内容: 我正在尝试检查java中的wait / notify如何工作。 码: 输出返回 我期望在执行notify()时,等待将结束并被打印。但似乎只有完成打印后才能打印。 问题答案: 对象监视器锁需要执行相同锁的单个引用。 在你的榜样,你是对的一个实例,但使用从。相反,您应该使用单个通用锁定对象…例如 输出… 并可能根据线程调度更改位置。 您可以尝试将睡眠排除在障碍之外。这将释放监视器锁定,从

  • 问题内容: 我了解到,调用对象的方法将释放对象监视器(如果存在)。 但是我对通过另一个线程调用该对象有一些疑问: (何时)等待线程唤醒,如果同时有另一个(第3个)线程拥有对象监视器? 如果在该对象上调用了第三个线程,等待线程将被唤醒吗? 是否可以确定线程是否正在等待通知特定对象(java 1.4 / java 5) 如果将在方法中调用会发生什么情况? 问题答案: 将唤醒在监视器上等待的一个线程。除

  • 问题内容: 我一直在考虑向Java语言架构师发送建议。 在同步块中 在线程离开同步块之后,它不能再调用lock.notifyAll()/ lock.notify()而不会发生异常。 忘记通知其他线程监视器持有者可能永远使他们(其他线程)等待(除非他们在其wait方法中放置了一些超时)。 我无法想象这种情况(在没有显式通知的情况下在同步块的末尾插入隐式通知)是不理想的。 相同的方法可以应用于同步方法

  • 我遇到了以下关于从生产者同步发送。我知道上下文生产者中的异步机制 在此将来调用get()将阻塞,直到相关请求完成,然后返回记录的元数据或引发发送记录时发生的任何异常。 什么是真正的意思相关联的请求完成,我是相当这不是指完整的请求,但在什么程度上这个短语是指?直到经纪人?直到生产者等使用的缓冲区...? 当ack=all与同步生产者和异步生产者一起使用时,它有什么不同?两个场景都被阻塞以进行确认?

  • 问题内容: 我越来越。我提到了这个问题,它解决了我的问题。第一个答案是 我的问题是为什么我们需要在同一个对象广告上进行同步? 据我的理解,当我们说 我们锁定了对象someObject,然后对其调用了wait()。 现在,另一个线程如何才能锁定同一对象以在其上调用notify()? 我想念什么? 问题答案: 为什么也需要锁? 想象一下这种情况: 现在想象一下其他地方没有任何锁定: 乍一看,整个声音总