java - 为什么此代码抛出非法状态监视器异常

标签 java multithreading java-threads thread-synchronization

我正在尝试使用共享对象的 notifyAll() 和 wait() 方法创建一个阻塞队列。但是这段代码抛出 IllegalMonitorStateException。我需要在哪里进行更改?

public class BlockingQueueNotifyAll<E> {

    private Queue<E> queue;
    private int max;
    private Object sharedQ = new Object();

    public BlockingQueueNotifyAll(int size) {
        queue = new LinkedList<>();
        this.max = size;
    }

    public synchronized void put(E e) {
        while(queue.size() == max) {
            try {
                sharedQ.wait();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
        queue.add(e);
        sharedQ.notifyAll();
    }


    public synchronized E take() throws InterruptedException {

        while(queue.size() == 0) {
            sharedQ.wait();
        }
        E item = queue.remove();
        sharedQ.notifyAll();
        return item;
    }
}

最佳答案

问题是您在 sharedQ 上调用了 notifyAllwait 但您在 sharedQ 上持有锁时并没有这样做 对象。 synchronized 您的方法将确保您获得对 BlockingQueueNotifyAll 对象的锁定。

来自 Object::wait文档:

The current thread must own this object's monitor.

synchronized (obj) {  // here you acquire lock on obj
         while (<condition does not hold>)
             obj.wait();  // here you call wait on obj while holding the lock on this object
         ... // Perform action appropriate to condition
}

因此,在您的情况下,您在对象上调用了 waitnotifyAll 而没有持有此对象的锁。

关于java - 为什么此代码抛出非法状态监视器异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57816614/

相关文章:

java - 在 Java 中使用同步

java - 不明白线程构造函数、start和run方法的输出顺序

java - 与棉花糖相比,牛轧糖要慢得多

java - 允许 Java JDK 11 HttpClient 的不安全 HTTPS 连接

java - 如何使用java程序删除英语中的停用词

java - 线程中的Android无限循环

java - 我如何/可以使用 base64 作为 Jasper 报告模板中的图像源?

c# 如何在不停止主线程的情况下在 2 个函数调用之间暂停

java - .start() 方法后的线程执行

java - 如何同步共享变量使这个程序安全?