我有一堆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()
,但我不知道这会如何导致它表现出奇怪的行为
关于可能导致这种情况的任何想法?
编辑:这里没有区别。减速是由于在进行此更改的同时更改了代码的不同部分,并且两者之间存在混淆。
答案 0 :(得分:3)
execute(...)
应与submit(...)
执行相同的操作。唯一的区别是submit(...)
会返回Future
。 ExecutorCompletionService
不需要将来,因为它将提交的任务包装在自己的内部Runnable
中。
必须对其他更改进行性能更改。我知道你向我们展示了ECS构造函数但是为了确保你没有将BlockingQueue
限制在ExecutorCompletionService
右边?使用有界队列将阻止线程完成并移动到下一个作业,直到作业出列。
我们可以看到更多代码吗?
答案 1 :(得分:0)
使用ExecutorService,您可以收集提交返回的期货和get()他们的结果吗?