Java 使用ExecutorService的管道模式中的多线程阶段
我有一个多级管道。每个阶段在单独的线程中运行,使用有界阻塞阵列队列进行通信。我试图在最慢的阶段使用多线程来提高吞吐量 问题:这方面的建议实施方式是什么?是否有一个库可以使这个实现更简单、更容易阅读 输入队列->阶段1 4线程->有界队列->阶段2 要求: 输入队列上的工作单元是独立的 工作单元是严格有序的——输出的顺序应该与输入的顺序相同 必须对阶段1进行节流-如果输出超过一定大小,则必须停止 阶段1中的异常将导致输出队列中出现毒药并终止ExecutorService。应尽最大努力放弃排队的任务 **我提议的执行:** 我正在考虑使用一个线程池执行器,线程数量有限 在每个工作单元上,将通过倒计时闩锁强制执行严格的命令。只有当前一个工作单元的闩锁为0且队列中有空间时,线程才能推送结果。这还考虑了节流,因为线程将阻塞,直到输出队列上有空间为止Java 使用ExecutorService的管道模式中的多线程阶段,java,multithreading,design-patterns,pipeline,executorservice,Java,Multithreading,Design Patterns,Pipeline,Executorservice,我有一个多级管道。每个阶段在单独的线程中运行,使用有界阻塞阵列队列进行通信。我试图在最慢的阶段使用多线程来提高吞吐量 问题:这方面的建议实施方式是什么?是否有一个库可以使这个实现更简单、更容易阅读 输入队列->阶段1 4线程->有界队列->阶段2 要求: 输入队列上的工作单元是独立的 工作单元是严格有序的——输出的顺序应该与输入的顺序相同 必须对阶段1进行节流-如果输出超过一定大小,则必须停止 阶段1中的异常将导致输出队列中出现毒药并终止ExecutorService。应尽最大努力放弃排队的任务
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必须等待某些事件时,该事件应通过向ExecutorService提交Runnable来启动操作B 在这种情况下,您应该创建自定义类而不是队列。这些类应该接受消息并在内部存储它们,或者根据一些规则提交实现Stage1或Stage2的任务,例如限制正在运行的Stage1任务的数量
至于订购,请用序列号替换对上一个任务的引用。我将在每个阶段使用ExecutorService。我会设计它,使线程池一直运行,而不是关闭。@foampile我的问题是什么是这个问题的最佳解决方案…是否有一个设计模式、库等,可以干净地实现我所看到的内存泄漏:字段CountDownLatch previousslatch;将所有工作单元编织在一个链接列表中,这样它们就不会被垃圾收集;将阻止工作线程进行有用的工作。实际上,从有界队列中提取时需要保持秩序,而不是插入时。@AlexeiKaigorodov非常有效的点,尤其是re。内存泄漏。通过在等待后设置previousLatch=null,可以修复内存泄漏。轻微的性能下降是一个问题,但我愿意为此付出代价,以获得严格的订购。关于正确实施这一点,您有什么建议?