簡體   English   中英

使用ExecutorService對管道模式中的階段進行多線程處理

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM