Parallel streams and the common pool
When .parallel() genuinely helps, which pool it borrows, and the traps that make it slower.
Open this lesson in the learning hubKey points
.parallel()splits the source, runs the pipeline on several workers and merges the partial results.- It runs on the shared common pool, sized to cores minus one. One slow task in there stalls every other user of it.
- Never do blocking I/O in a parallel stream. Give that work its own executor, or use virtual threads.
- It pays off with a lot of data, cheap splitting and independent work. Arrays and ranges split well,
LinkedListdoes not. - Encounter order still holds for ordered collectors, so the parallel answer matches the serial one exactly.
- The lambdas must be stateless. Writing into a shared list from a parallel stream is a race you added yourself.
Example
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) throws Exception {
long serial = IntStream.rangeClosed(1, 1_000_000).asLongStream().map(n -> n * n).sum();
long parallel = IntStream.rangeClosed(1, 1_000_000).parallel().asLongStream().map(n -> n * n).sum();
System.out.println("serial : " + serial);
System.out.println("parallel : " + parallel + " (split, mapped, merged)");
List<String> ordered = IntStream.rangeClosed(1, 6).parallel()
.mapToObj(n -> "v" + n)
.toList(); // encounter order is still preserved
System.out.println("ordered : " + ordered);
System.out.println("common pool: " + ForkJoinPool.commonPool().getParallelism() + " workers, shared by the whole JVM");
ForkJoinPool own = new ForkJoinPool(2); // keep slow work off the common pool
long inOwnPool = own.submit(() -> IntStream.rangeClosed(1, 100).parallel().asLongStream().sum()).get();
own.shutdown();
System.out.println("own pool : " + inOwnPool);
}
}
Parallel streams suit big, CPU-bound, side-effect-free work. Measure before and after.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Multithreading course, and every lesson in it is listed on the Multithreading contents page.