2 回答
TA贡献1820条经验 获得超10个赞
问题是:
对于“满”和“空”状态,您只有一个共享的等待条件
您正在运行两个消费者线程(“consumerWorker”和“delayedConsumer”)和一个生产者线程(“ ProducerWorker”)
你没有像你应该的那样重新检查 while 循环中的条件
可能发生的事情是:
两个消费者线程都看到缓冲区为空
生产者线程将一项放入缓冲区并发出通知。
单个消费者线程唤醒并处理一项。缓冲区现在是空的。然后它会发出通知。
第二个消费者线程醒来(而不是像您预期的那样的生产者),不检查缓冲区是否为空,并尝试访问索引 -1 处的缓冲区。
您从通话中醒来后需要重新检查情况wait
。将 更改if
为while
. 以下是如何为消费者做到这一点;您需要为制作人做同样的事情。
void consume() {
synchronized (key) {
while (isEmpty()) {
try {
key.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer[--count] = 0;
key.notify();
}
}
这样消费者就不会被来自notify
其他消费者线程的 所迷惑。
TA贡献1807条经验 获得超9个赞
你的缓冲区长度为 10
buffer = new int[10];
因此,每当您的计数变量超过数组容量(即 10)时,就会很明显
private volatile static Integer count;
你会得到ArrayIndexOutOfBoundsException
您生产更多,消耗更少,消耗更少,并且生产/消费的执行不是顺序的,它更像是循环。
添加回答
举报