2012-11-23 35 views
-2

我想協調一個生產者和消費者線程問題。生產者將10個對象放在隊列中。這是生產者的運行方法只包括一個簡單的循環來添加10個對象,然後完成。當隊列已滿(隊列大小爲10)時,會在隊列的add方法中調用wait() - >。在消費者方面,消費者從窺視物體開始,然後開始消除它們。我遇到的問題是,在運行程序的大約50%的情況下,輸出在生產者將10個對象放入隊列後終止。程序正常工作的另外50% - 即消費者將所有物體取走。我之前解決這個問題的方法是在生產者的run方法中創建一個新的消費者線程。所以一旦生產者把十個對象放在隊列中,新的消費者線程就被創建了,我使用join()來同步操作。不過,我希望通過等待並通知該流程。有人能告訴我做錯了什麼嗎?謝謝生產者/消費者使用等待和通知

@Override 
    public synchronized boolean add(Process element) { 
    if(isFull()) 
    { 
     waitForNotify(); 
    } 

    else 
    {   

     queue.add(element); 



    } 
    return true; 
} 

    private void invokeNotify() { 
    try { 
     notify(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

    private void waitForNotify() { 
    try { 
     wait(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

} 

    @Override 
    public synchronized boolean offer(Process element) throws IllegalStateException { 
     queue.add(element); 
     this.queue = newHeapSort.heapify(queue, queue.size()); 
     return true; 



} 

    @Override 
    public synchronized Process peek() { 
    if(queue.isEmpty()) 
    { 
     waitForNotify(); 
    } 
    return(queue.get(0)); 

} 

    @Override 
    public synchronized Process head() {  
    if(queue.isEmpty()) 
    { 
     invokeNotify(); 
    } 

     Process head = queue.get(0); 
     queue.remove(0); 


     return head; 


} 

回答

3

生產者從不通知消費者線程。所以如果消費者是第一個開始,它會發現隊列是空的,並且永遠等待。

我只是簡單地使用一個BlockingQueue,它爲你做。

如果你真的想用wait()notify(),你將需要:

  • 使用循環在你的wait()來電,並返回到等待狀態,如果醒來的條件是不正確的
  • 決定當製片人應通知(通常情況下,當它把隊列中的項目)
  • 決定當消費者應通知(通常情況下,當它從隊列中刪除的項目)
  • 決定當消費者應等待(通常在隊列爲空時)
  • 決定生產者何時應該等待(通常在隊列滿時)
  • stop ignore InterruptedException。讓他們傳播。

我會使用notifyAll(),如果有多個生產者或消費者,這也將確保一切正常。

+0

感謝您的指點。我會將它們考慮在內供將來參考。我的問題在這個場合更加微不足道 - 線程沒有「正確地開始和加入」。再次感謝提示。 –