ExecutorCompletionservice

ExecutorCompletionservice

我有一堆Callable,我想并行运行并获取结果。我的机器上有12个核心;以下代码在100%CPU使用率下可以正常工作:

exec = Executors.newFixedThreadPool(maxThreads);
for(Callable<T> job : jobs) exec.submit(job);
// System runs at 100% CPU.

但是,这种情况并不理想,因为我想在任务返回时处理它们的结果。因此,我将ExecutorService包裹在CompletionService中,将Future放入队列中:
exec = Executors.newFixedThreadPool(maxThreads);
ecs = new ExecutorCompletionService<T>(exec);
for(Callable<T> job : jobs) ecs.submit(job);
// System runs threads one at a time.

现在我的代码运行速度慢了12倍。在检查了基础代码之后,我看到ExecutorCompletionService调用了execute()而不是ExecutorService上的submit(),但是我看不到这将如何导致它表现出怪异的行为。

关于什么可能导致此的任何想法?

编辑:这里没有区别。变慢是由于在进行此更改的同时对代码的不同部分进行了更改,并且两者之间存在混淆。

最佳答案

execute(...)应该与submit(...)具有相同的功能。唯一的区别是submit(...)返回FutureExecutorCompletionService不需要将来,因为它将提交的任务包装在其自己的内部Runnable中。

性能更改必须与其他更改一起执行。我知道您向我们展示了ECS构造函数,但只是为了确保您没有将有限的BlockingQueue传递给ExecutorCompletionService,对吗?使用有界队列将使线程无法完成并转移到下一个作业,直到作业出队。

我们可以看到更多代码吗?

关于java - ExecutorCompletionService仅在单个线程中运行,但是ExecutorService使用所有CPU,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14510678/

10-09 13:23