package ch.claude_martin; import java.util.List; import java.util.concurrent.*; import java.util.stream.*; public final class SomeClass implements Callable { private final int value; public SomeClass(int i) { this.value = i; } @Override public Integer call() throws Exception { System.out.println("started: " + value); Thread.sleep((long) (1000 * Math.random())); System.out.println("finished: " + value); return value; } public static void main(String[] args) throws InterruptedException { // List of 10 instances of SomeClass: List tasks = IntStream.range(0, 10).mapToObj(i -> new SomeClass(i)) .collect(Collectors.toList()); // This would work, but is sequential instead of parallel: // tasks.stream().map(ForkJoinPool.commonPool()::submit) // This would work, but it messes up the order: // tasks.parallelStream().map(ForkJoinPool.commonPool()::submit) // Process the list and print all results in correct order: ForkJoinPool.commonPool().invokeAll(tasks).stream() .map(t -> { try { return t.get(); } catch (InterruptedException | ExecutionException e) { // Java isn't exactly elegant when it comes to streams and exceptions throw new RuntimeException(e); } }).forEach(System.out::println); // Not necessary, but to really make sure the tasks are all processed: ForkJoinPool.commonPool().awaitTermination(100, TimeUnit.SECONDS); System.out.flush(); } }