ExecutorCompletionService仅在单个线程中运行,但ExecutorService使用所有CPU

时间:2013-01-24 21:01:18

标签: java concurrency threadpool executorservice

我有一堆Callable我希望并行运行并获得结果。我的机器上有12个核心;以下代码按预期工作,CPU使用率为100%:

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(),但我不知道这会如何导致它表现出奇怪的行为

关于可能导致这种情况的任何想法?

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

2 个答案:

答案 0 :(得分:3)

execute(...)应与submit(...)执行相同的操作。唯一的区别是submit(...)会返回FutureExecutorCompletionService不需要将来,因为它将提交的任务包装在自己的内部Runnable中。

必须对其他更改进行性能更改。我知道你向我们展示了ECS构造函数但是为了确保你没有将BlockingQueue限制在ExecutorCompletionService右边?使用有界队列将阻止线程完成并移动到下一个作业,直到作业出列。

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

答案 1 :(得分:0)

使用ExecutorService,您可以收集提交返回的期货和get()他们的结果吗?