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

标签 java concurrency threadpool executorservice

我有一堆 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 倍。检查底层代码后,我发现 ExecutorCompletionServiceExecutorService 上调用了 execute() 而不是 submit(),但我不明白这会如何导致它表现出奇怪的行为。

关于可能导致这种情况的原因有什么想法吗?

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

最佳答案

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

性能变化必须对其他一些变化进行。我知道您向我们展示了 ECS 构造函数,但只是为了确保您没有将有界 BlockingQueue 传递给 ExecutorCompletionService 对吗?使用有界队列会阻止线程完成并移动到下一个作业,直到作业出队。

我们能看到更多代码吗?

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

相关文章:

java - 通过 Java mysql admin-api 启动和停止 Cloud SQL

java - 弯曲的 vector 绘图未获得全宽度

java - 在 JfxPane 中创建上下文菜单

java在不同线程中访问一个对象

java - 多线程中的线程池

Python:将Pool对象传递给不同进程中的函数

java - 在 Windows 中更改 org.eclipse.swt.widgets 背景颜色

PHP信号量替代?

java - 如何在java中强制信号量排序

java - WEB应用中的缓存线程池性能