chr*_*tek 2 java queue multithreading blockingqueue data-structures
我试图找出是否有可能有一个多生产者/多个消费者队列,我可以使用notify()而不是notifyAll().例如,在下面的实现中(源代码:这里),你不能只是简单地切换notifyAll()for notify().你不能切换的原因并不是很明显,所以我会把它作为预告片给那些想要帮助我理解这个问题的人.
所以下面的代码被破坏了:
public class BlockingQueue {
private Object lock = new Object();
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public void enqueue(Object item)
throws InterruptedException {
synchronized(lock) {
while(this.queue.size() == this.limit) {
lock.wait();
}
if(this.queue.size() == 0) {
lock.notify();
}
this.queue.add(item);
}
}
public Object dequeue()
throws InterruptedException{
synchronized(lock) {
while(this.queue.size() == 0){
lock.wait();
}
if(this.queue.size() == this.limit){
lock.notify();
}
return this.queue.remove(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
xag*_*gyg 10
以下步骤导致我们陷入僵局.我们将限制设置为1以保持示例简短.
E3尝试入队 - 检查等待循环 - 已经满 - 等待
D1尝试出队 - 并且正在执行同步块
D3尝试出列 - 由于D1而进入(同步)块时阻塞
D1正在执行enqueue - 获取项目,调用notify,退出方法
D3在D2之后进入块,但在E2之前,检查等待循环,队列中没有其他项,因此等待
现在有E3,D2和D3在等!
最后E2获取锁,排队项,调用通知,退出方法
E2的通知唤醒E3(记住任何线程都可以被唤醒)
SOLUTION:用notifyAll替换notify