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