2 回答

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊
問題是:
對于“滿”和“空”狀態(tài),您只有一個(gè)共享的等待條件
您正在運(yùn)行兩個(gè)消費(fèi)者線程(“consumerWorker”和“delayedConsumer”)和一個(gè)生產(chǎn)者線程(“ ProducerWorker”)
你沒有像你應(yīng)該的那樣重新檢查 while 循環(huán)中的條件
可能發(fā)生的事情是:
兩個(gè)消費(fèi)者線程都看到緩沖區(qū)為空
生產(chǎn)者線程將一項(xiàng)放入緩沖區(qū)并發(fā)出通知。
單個(gè)消費(fèi)者線程喚醒并處理一項(xiàng)。緩沖區(qū)現(xiàn)在是空的。然后它會發(fā)出通知。
第二個(gè)消費(fèi)者線程醒來(而不是像您預(yù)期的那樣的生產(chǎn)者),不檢查緩沖區(qū)是否為空,并嘗試訪問索引 -1 處的緩沖區(qū)。
您從通話中醒來后需要重新檢查情況wait
。將 更改if
為while
.?以下是如何為消費(fèi)者做到這一點(diǎn);您需要為制作人做同樣的事情。
? ? void consume() {
? ? ? ? synchronized (key) {
? ? ? ? ? ? while (isEmpty()) {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? key.wait();
? ? ? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? buffer[--count] = 0;
? ? ? ? ? ? key.notify();
? ? ? ? }
? ? }
這樣消費(fèi)者就不會被來自notify
其他消費(fèi)者線程的 所迷惑。

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊
你的緩沖區(qū)長度為 10
buffer = new int[10];
因此,每當(dāng)您的計(jì)數(shù)變量超過數(shù)組容量(即 10)時(shí),就會很明顯
private volatile static Integer count;
你會得到ArrayIndexOutOfBoundsException
您生產(chǎn)更多,消耗更少,消耗更少,并且生產(chǎn)/消費(fèi)的執(zhí)行不是順序的,它更像是循環(huán)。
添加回答
舉報(bào)