2012-03-21 66 views
1

我想,和失敗,在Java中實現生產者消費者模式,受到以下限制:生產者消費者在Java中有一個UI切換

  • 生產者生產地(並在消費者從消費)一個隊列具有有限大小
  • 沒有與按鈕切換生產者和消費者,分別
  • 當隊列不滿生產者按鈕被切換活性生產者只應產生的用戶界面,
  • 只有當隊列不爲空時,消費者纔會消耗消費者按鈕處於活動狀態。
  • 生產和消費都應該可以同時進行。 (事實上​​,有生產將至少儘可能消耗,有時更快。)

我的想法是爲執行緩衝器爲有限大小的的LinkedBlockingQueue,以處理與所述隊列中的條件空/滿狀態 - 當試圖放入一個完整的隊列或從一個空隊列取出時應該阻塞。然後,在生產者和消費者上使用布爾狀態,觸發按鈕。最後,在生產者和消費者中使用while/wait /循環,並在代碼中通知按鈕。

類似下面,對於製片方:

while (true) { 
    if (!producing) { wait(); } 
    // generate a bunch of data and and finally   
    // Save this chunk of data 
    buffer.addData(data); 
    } 

而且在生產者按鈕的代碼中,我們既切換生產狀態,並調用一個方法在生產者自我通知。

問題:一旦生產者正在生產,即使用戶界面(在Swing中實現)也失去響應性,他們的輪詢非常困難。我可以通過填寫wait(1);聲明來解決這個問題,但是出於各種不可接受的原因,這是不可接受的。有些延遲是不可避免的,但是每次通過循環1毫秒的延遲都不起作用。

我也不相信我對LinkedBlockingQueue有正確的理解,因爲如果我讓隊列填滿,我仍然失去了UI響應。我清楚地誤解了Java中運行的操作,因爲我嘗試了多種方法,而且這是最接近的;先前的方法試圖在沒有LinkedBlockingQueue的情況下「手動」處理滿/空條件是可悲的失敗。

任何意見,將不勝感激。當然,我試圖做的事情(鎖定兩個條件而沒有過多的投票)並非不可能,是嗎?

回答

4

discussion包括程序TwoTimer,其中javax.swing.Timer遞增一個int在100Hz,而java.util.TimerTask樣品在1Hz的值。變體將樣本存儲在LinkedBlockingQueue中,形成最近的歷史隊列。它與您的任務沒有直接關係,但它說明了響應式GUI的基本要求:從不阻止事件派發線程。該示例使用invokeLater()執行下一個收集。

還考慮nextGaussian()模擬延遲,如圖所示here

順便說一下,您可能會喜歡這個動畫爲幾何形狀隊列的example

2

你所描述的應該可以正常工作。發佈你的實際代碼(抽象出實際生產和實際消費)將會有所幫助。你說

它輪詢這麼辛苦甚至UI失去響應

,這似乎意味着你是濫用的LinkedBlockingQueue。您不應該反覆輪詢隊列。您應該從隊列中取出一個項目,處理它,然後檢查生產標誌,並在UI調用notifyAll()的監視器上生成和排隊項目,或wait()。

+0

但生產和消費**可能同時啓用,但它們不是**必需**。所以生產只能在沒有消費的情況下啓用。我明天會更新附加的代碼。 – Novak 2012-03-21 06:16:46