Java Concurrency Interview

Fork/join and parallel streams question 106 of 180 mid

Why is forEach on a parallel stream dangerous, and what should you use?

forEach makes no ordering promise and calls your lambda from every worker thread at once. Adding to an ArrayList from it corrupts the list; adding to a Collectors.toList result via a side effect is the same bug with more steps.

List<String> out = new ArrayList<>();
stream.parallel().forEach(out::add);          // race, lost elements, occasional exception

List<String> out = stream.parallel().collect(toList());   // correct and faster

collect is designed for this: each thread accumulates into its own container and the containers are merged. forEachOrdered restores encounter order at the cost of the parallelism you asked for. And even a synchronized list is the wrong fix, since every element then serialises on one lock.

parallel-streams api

Quiz yourself on Fork/join and parallel streams Suggest a correction