2016-01-28 63 views
1

我有一個正常工作的生產者/消費者模式。 它有1個生產者和N個消費者。Producer消費者修改

現在我##標題##試圖生產,然後同時消費,但仍然使用1生產者和N消費者線程。

所以基本上它應該像農產品() - >消費(),生產() - >消費(),生產() - >消耗()...

,但現在,我有多個消費者線程我希望他們在該條件等待(),所以如果之後產生() - >消耗()另一個消耗()發生的地方它等待。

所以說我有1生產者和消費者4它可能看起來像這樣:

農產品() - >消耗() - >消耗()await->消耗()等待() - >消耗。 () - >生產() - > ...

問題:代碼的作品,但我不明白,後生產者線程進入cond.await();他怎麼能仍然調用cond1.signalAll();? 連續代碼不應該在cond.await()處停止嗎?

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

public class Processor { 
    private Lock lock = new ReentrantLock(); 
    private Condition cond = lock.newCondition(); 
    private Condition cond1 = lock.newCondition(); 
    private int Counter = 0; 

    public void produce() throws InterruptedException { 
     while(true) { 
      lock.lock(); 
      try { 
       Counter++; 
       System.out.println("Increased by one"); 
       Thread.sleep(1000); 
       cond.await(); 
       cond1.signalAll(); 
      } finally { 
       lock.unlock(); 
      } 
     } 
    } 

    public void consume() throws InterruptedException{ 
     while(true) { 
      lock.lock(); 
      try { 
       while(Counter==0) { 
        cond1.await(); 
       } 
       Counter--; 
       System.out.println("Decreased by one!"); 
       Thread.sleep(1000); 
       cond.signalAll();   
      } 
      finally { 
       lock.unlock(); 
      } 
     } 
    } 
} 

回答

1

你生產者/消費者安裝可能會失敗,我將討論如何那是原因,但最初將解釋爲什麼它的工作原理有點。生產者調用cond1.signalAll的原因是你如何設置生產者消費者溝通。計數器字段是生產者可以調用cond1.signalAll方法的原因。在這種情況下有可能的情況。

讓我們開始假設生產者在任何消費者之前獲得鎖定。生產者然後會增加計數器,並使用cond.await調用將自己置於等待狀態。這將導致製片人放棄其鎖定並允許其中一名消費者獲得鎖定。獲得鎖定的消費者將看到計數大於零並繼續減少計數器。然後它會調用cond.signalAll並使生產者收回鎖。消費者然後釋放鎖並嘗試重新獲得鎖。如果生產者重新獲得鎖定,它將執行上面提到的相同過程。如果消費者獲得該鎖,並且它會注意到該計數器爲零,並通過調用cond1.await將自身置於等待狀態。在這種情況下,製片人最終會獲得鎖定。

另一種情況是消費者在生產者獲得鎖之前獲得鎖。消費者會看到計數器爲零,它將使用cond1.await將自己置於等待狀態。它會放棄它的鎖,另一個線程會獲得鎖。生產者然後可以獲得鎖定並且能夠增加計數器並且使自己處於等待狀態。然後消費者將獲得鎖定並能夠在向生產者發信號之前消費櫃檯。

如果所有的消費者在生產者獲得鎖之前獲得鎖,會發生什麼?在這種情況下,消費者將執行與上述相同的步驟。最終生產者將獲得鎖定並增加計數器。請注意,在這種情況下,製作人會在消費者醒來之前等待。這將導致你的製片人/消費者永遠等待而不做任何工作。這是唯一會導致系統失敗的情況。因此,建議您首先表明您在製作人處於等待狀態之前已經爲消費者工作。請注意,這種情況只有在您最初啓動生產者/消費者線程時纔會發生。通過啓動所有消費者線程並等待一段時間,然後啓動生產者,您可以輕鬆地重現此情況。這將產生上述情況。這實際上是一個你只需要考慮的邊界情況。