1

我在這個question中看到了一段代碼,我不明白(很可能是因爲這個領域的初學者)。這個問題是關於「一個明顯的種族情況,有時生產者會完成,發出信號,消費者工作人員將在消耗隊列中的所有東西之前停止。」在這個多線程的java代碼中真的存在競爭條件嗎?

  1. 在我的理解,「isRunning」將在消費者進行設置後,才生產者決定不在隊列中不再添加項目。因此,如果消費者線程將isRunning視爲FALSE,然後看到inputQueue爲空,那麼未來無法再有更多任務添加到隊列中。顯然,我錯了,錯過了一些東西,因爲沒有人回答這個問題說這個問題的場景是不可能的。那麼,有人可以解釋什麼樣的事件導致了這種競爭狀態?

  2. 事實上,我發現有其他問題。例如,如果多個消費者線程看到生產者正在運行,並且說隊列有一個項目,則許多線程可能會進入被阻止的'take'。如果生產商STOPS現在只有一個線程會從'take'中出來,其他線程永遠被阻止在'take'上。有趣的是,沒有人回答這個問題也指出了這個問題。那麼,我對此的理解也可能是錯誤的!

我沒有想在這個問題有其添加爲評論,因爲這是一個老問題,我懷疑可能永遠不會得到回答! 我在這裏複製/放置該問題的代碼以供快速參考。

public class ConsumerWorker implements Runnable{ 

private BlockingQueue<Produced> inputQueue; 
private volatile boolean isRunning = true; 

public ConsumerWorker(BlockingQueue<Produced> inputQueue) { 
    this.inputQueue = inputQueue; 
} 

@Override 
public void run() { 
    //worker loop keeps taking en element from the queue as long as the producer is still running or as 
    //long as the queue is not empty: 
    while(isRunning || !inputQueue.isEmpty()) { 
     System.out.println("Consumer "+Thread.currentThread().getName()+" START"); 
     try { 
      Object queueElement = inputQueue.take(); 
      //process queueElement 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

//this is used to signal from the main thread that he producer has finished adding stuff to the queue 
public void setRunning(boolean isRunning) { 
    this.isRunning = isRunning; 
} 

回答

1

我認爲原來的問題的OP大概意思

while(isRunning && !inputQueue.isEmpty()) 

而不是

while(isRunning || !inputQueue.isEmpty()) 

前者顯然產生由原始的海報(*)中描述的問題,而後者確實存在你在第二點中描述的問題。那裏有一個簡單的監督,但現在我們可以注意到這兩種方法都是不正確的。

(*),並以某種方式假定隊列永遠不會爲空。

+1

我有同樣的想法。我確實檢查了關於該問題的「編輯」,看看OP是否改變了問題並修改了操作員。但是,他沒有。該運算符總是||。這個問題中沒有人質疑這個問題! – brainOverflow 2013-04-21 19:16:39

+0

這可能是因爲它沒有必要,因爲這兩個表達式都是錯誤的,所以解決方案是必需的。一個簡單的監督真的。 – didierc 2013-04-21 19:51:57

0

你在兩個問題中都是正確的。是的&&是正確的,而||不是。至於第二個問題,答案是使用poison pill或超時,兩種方式解決問題。

至於我,我想創建它彙集兩個隊列和isRunning可變新的同步的類,從而改變isRunning導致異常在take()從而信令工作結束。

+0

我真的很喜歡@PeterLawrey迴應最好的。但那就是我。 – brainOverflow 2013-04-22 17:44:17