I have a list of heavy tasks that should be run in parallel. I like the java Stream API and don't want to touch Executors
directly, for that reason I've written the following code:
Set<Runnable> tasks = Set.of(heavyTask(),…);
tasks.parallelStream().forEach(Runnable::run);
Quite often (not always!) my concurrency tests fails during “heavy task” execution. OK, probably it's a race condition. I've rewritten the code using Executors
directly:
try {
Set<Callable<Object>> tasks = Set.of(heavyTask(),…);
Executors.newFixedThreadPool(4)
.invokeAll(tasks).forEach(future->{
try {
future.get();
} catch (InterruptedException | ExecutionException ignore) {
}
});
} catch (InterruptedException ignore) {
}
The problem with heavy tasks is gone. I'm really confused. I thought that parallelStream()
uses Executors
under the hood and it's almost the same. Is there any difference between .parallelStream()
and ExecutorService
? Or maybe forEach
isn't correct termination operation in the first code example?