[英]Multi-threading a stage in the pipeline pattern with ExecutorService
我有一個多階段的管道。 每個階段都在單獨的線程中運行,並使用有限的BlockingArrayQueues進行通信。 我正在嘗試對最慢的階段進行多線程處理以提高吞吐量。
問題:推薦的實現方法是什么? 是否有一個庫可使該實現更簡單易讀?
輸入隊列->階段1(4個線程)->有界隊列->階段2
要求 :
輸入隊列上的工作單元是獨立的。
工作單元是嚴格排序的-輸出應與輸入順序相同。
必須對第1階段進行調節-如果輸出超過特定大小,則必須停止。
第1階段的異常應導致輸出隊列上出現“毒葯”並終止ExecutorService。 排隊的任務應盡力而為。
**我建議的實施方式:**
我正在考慮使用線程數量有限的ThreadPoolExecutor。
嚴格的排序將通過每個工作單元上的CountDown鎖來強制執行。 如果前一個工作單元的鎖存器為0,並且隊列中有空間,則線程只能推送結果。 由於線程將阻塞,直到輸出隊列中有空間,這也可以節流。
class WorkUnit {
CountDownLatch previousLatch;
CountDownLatch myLatch;
}
class MyRunnable extends Runnable {
public void run() {
//do work...
previousLatch.await();
ouputQueue.put( result );
myLatch.countDown();
}
}
異常處理讓我有些困惑。 我正在考慮重寫ThreadPoolExecutor.afterExecute(),如果有異常,它將調用shutdownNow()。
class MyThreadPoolExecutor extends ThreadPoolExecutor {
protected void afterExecute(Runnable r, Throwable t) {
if(t != null) {
//record exection, log, alert, etc
ouput.put(POISON_PILL);
shutdownNow();
}
}
}
使用ExecutorService需要完全異步的設計,而無需使用諸如CountDownLatch.countDown()
或BlockingQueue.take()
類的阻塞操作。 當動作B必須等待某些事件時,則該事件應通過將Runnable
提交給ExecutorService
來啟動動作B。
在這種情況下,您應該創建自定義類而不是隊列。 根據某些規則(例如,限制正在運行的Stage1任務的數量),這些類應該接受消息並將其存儲在內部,或者提交實現Stage1或Stage2的任務。
至於訂購,請用序列號替換對先前任務的引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.