ExecutorCompletionService only runs on one thread, but ExecutorService uses all processors
I have a group Callable
that I want to run in parallel and get the results. I have 12 cores on my machine; the following code works as expected at 100% CPU usage:
exec = Executors.newFixedThreadPool(maxThreads);
for(Callable<T> job : jobs) exec.submit(job);
// System runs at 100% CPU.
However, this situation is not ideal because I want to process the results of tasks as they are returned. Hence, I wrap ExecutorService
in CompletionService
, which enqueues the Future
way they are executed:
exec = Executors.newFixedThreadPool(maxThreads);
ecs = new ExecutorCompletionService<T>(exec);
for(Callable<T> job : jobs) ecs.submit(job);
// System runs threads one at a time.
Now my code runs 12x slower. After checking the underlying code, I can see what ExecutorCompletionService
is calling execute()
in ExecutorService
and not submit()
, but I cannot see how that might cause its strange behavior.
Any ideas as to what might be causing this?
EDIT: There is no difference here. The slowdown was caused by a change to a different part of the code, at the same time that change was made and there was confusion between the two.
source to share
execute(...)
should work the same way as submit(...)
. The only difference is what a submit(...)
returns Future
. ExecutorCompletionService
does not need the future, since it transfers the sent task to its internal one Runnable
.
The performance change should be related to some other changes. I know that you are showing us the ECS constructor, but to make sure you don't go bounded BlockingQueue
to the ExecutorCompletionService
right? Using a bounded queue will stop threads from completing and moving on to the next job until the jobs are canceled.
Can we see more code?
source to share