Jam*_*mes 8 java scala threadpool actor akka
有大量的任务.每个任务都属于一个组.要求是每组任务应该像在单个线程中执行一样顺序执行,并且吞吐量应该在多核(或多CPU)环境中最大化.注意:还有大量的组与任务数量成比例.
天真的解决方案是使用ThreadPoolExecutor并同步(或锁定).但是,线程会相互阻塞,吞吐量不会最大化.
有什么好主意吗?或者是否存在满足要求的第三方库?
一种简单的方法是将所有组任务“连接”成一个超级任务,从而使子任务串行运行。但这可能会导致其他组延迟,除非其他组完全完成并在线程池中腾出一些空间,否则这些组不会启动。
作为替代方案,请考虑链接小组的任务。下面的代码说明了这一点:
public class MultiSerialExecutor {
private final ExecutorService executor;
public MultiSerialExecutor(int maxNumThreads) {
executor = Executors.newFixedThreadPool(maxNumThreads);
}
public void addTaskSequence(List<Runnable> tasks) {
executor.execute(new TaskChain(tasks));
}
private void shutdown() {
executor.shutdown();
}
private class TaskChain implements Runnable {
private List<Runnable> seq;
private int ind;
public TaskChain(List<Runnable> seq) {
this.seq = seq;
}
@Override
public void run() {
seq.get(ind++).run(); //NOTE: No special error handling
if (ind < seq.size())
executor.execute(this);
}
}
Run Code Online (Sandbox Code Playgroud)
优点是不使用额外的资源(线程/队列),并且任务的粒度比简单方法中的更好。缺点是所有小组的任务都应该提前知道。
- 编辑 -
为了使这个解决方案通用且完整,您可能需要决定错误处理(即,即使发生错误,链是否继续),并且实现 ExecutorService 并将所有调用委托给底层执行器也是一个好主意。