繁体   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