2012-12-07 69 views
1

我有三個工作線程從主線程。主線程將對象放入BlockingQueue。如果隊列沒有足夠的數據,只能說一個對象。其他兩個線程保持等待狀態。如何我信號那些其他兩個等待線程(因爲調用queue.take())終止?Java工作線程,終止條件

這樣做的一種方法是傳遞隊列上的最後一個髒對象以使其他陳舊線程讀取並終止。有沒有其他優雅的解決方案?

public void run() { 
if (log.isInfoEnabled()) { 
    log.info("Entering method 'run' " + this.getName()); 
} 
try { 
    while (!noMoreData || !queue.isEmpty()) { 
     String data = queue.take(); 
     ... 
     ... 
     doSomething(); 
    } 
    if (log.isInfoEnabled()) { 
     log.info("noMoreData =" + noMoreData + ", queue empty=" + queue.isEmpty() + "....Terminating thread..." + this.getName()); 
    } 
} catch (InterruptedException ie) { 
    log.error(ie); 
} finally { 
    //DONE SIGNAL 
    doneSignal.countDown(); 
    log.info(this.getName() + " finished."); 
} 
} 
+0

你能描述爲什麼你想過早地結束這個線程而阻塞隊列嗎?通常你會想讓線程正常地死掉,所以我只是好奇你的場景。 –

+0

排隊一個'毒丸'終止請求對象是一個相當常見的技術 - 它足夠優雅,所以爲什麼要使用其他任何東西? –

回答

1

您應該使用您配置的隊列(大小和數據結構)使用ExecutorService。

然後,您有一個關閉消息(Runnable),您將提交給調用#shutdown()的executorservice。只需在隊列中最後提交該消息。

該方法具有很高的可擴展性,因爲您可以用真正的消息隊列替換executorservice。

+0

我正在研究此解決方案,但試圖弄清楚如何... – gpa

+0

使用Future更容易檢測和關閉 – gpa

1

Thread.interrupt()會滿足您的需求嗎?如果保持對三個線程的引用,則可以中斷其他兩個線程,從而導致take()方法拋出InterruptedException。

+0

是的,中斷每個消費線程。它看起來像run方法已經被寫入,所以它在被中斷時會乾淨地終止它自己,並且中斷的目的幾乎指示一個線程它應該清理並終止它自己。 – VGR