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
您生產更多,消耗更少,消耗更少,并且生產/消費的執行不是順序的,它更像是循環。
添加回答
舉報