我正在尝试使用共享对象的 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
上调用了 notifyAll
和 wait
但您在 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
}
因此,在您的情况下,您在对象上调用了 wait
和 notifyAll
而没有持有此对象的锁。
关于java - 为什么此代码抛出非法状态监视器异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57816614/