2

我有以下情況:生產者 - 消費者:怎麼知道通知prodcution完成

  1. 閱讀從數據庫
  2. 數據做工作「計算」
  3. 結果寫入數據庫

我有一個線程從數據庫讀取並將生成的對象放入BlockingQueue。這些對象的體重非常大,因此隊列限制了內存中對象的數量。 多個線程從隊列中取對象,執行工作並將結果放入第二個隊列中。 最終線程從第二個隊列獲取結果並將結果保存到數據庫。

問題是如何防止死鎖,例如。 「計算線程」需要知道何時不會有更多的對象被放入隊列。 目前我通過傳遞線程(可調用)的引用來實現此目的,並在poll或offer之前檢查thread.isDone(),然後如果元素爲null。我還檢查隊列的大小,只要有元素,就必須消耗。使用take或put會導致死鎖。

有沒有更簡單的方法來實現這一目標?

+0

可能是一個愚蠢的http://stackoverflow.com/questions/5326013/proper-implementation-of-producer-consumer-scenario-and-graceful-termination-of – 2011-09-06 05:19:45

回答

0

當你確定沒有更多的任務要到隊列中時,其中一種方法是將「虛擬」或「中毒」消息作爲隊列中的最後一條消息。例如,在把與db查詢的最後一行有關的消息。因此,生產者在隊列中放置了一個虛擬消息,消費者在接收到這個虛擬消息時就知道在這批中沒有更多有意義的工作。

+0

我更像是一個生產者 - 消費者/生產者 - 消費者模式。中間部分消耗數據,然後將結果轉發給其他消費者。問題是我有這個「中間部分」的多個實例。這是艱苦工作完成的地方。問題是「虛擬數據」可以比以前的「真實數據」更快地通過這條鏈,因爲虛擬物上沒有工作。 –

+0

虛擬數據或posion消息只是爲了避免死鎖情況;所以你知道沒有更多的消息會到達。你也可以使用倒計時鎖存器或其他方法來跟蹤已經啓動的任務的完成情況。 – Scorpion

0

也許你應該看看CompletionService

它被設計成執行相結合,在一個隊列功能。 任務即完成執行將可以從完井服務通過

completionServiceInstance.take() 

然後,您可以再次使用其他執行人3.填寫即與DB的結果,你將與來自completionServiceInstance採取的結果饋送。

+0

這不會幫助我,因爲我沒有傳遞大量任務,而是從數據庫生成對象。我只有3個任務必須並行運行1.從數據庫中讀取2.執行工作3.將結果寫入數據庫。它們必須並行才能限制內存使用量,因爲讀寫操作比實際工作快得多。 –

相關問題