Parallel Streams

Streams · lesson 14 of 42 · 5 min read

When parallel streams genuinely speed things up, and when they quietly make it worse.

Open this lesson in the learning hub

Key points

  • .parallel() or parallelStream() splits the work across the shared ForkJoin common pool.
  • It helps with lots of elements, real CPU work per element, and a source that splits cheaply: arrays, ranges, ArrayList.
  • It hurts with small data, trivial operations, linked or iterator-based sources, and anything that blocks on I/O.
  • The common pool is process-wide. One slow parallel stream starves every other one in the JVM.
  • Ordered terminal ops still return the right order. forEach promises nothing in parallel; forEachOrdered does.
  • Never mutate shared state from a parallel lambda. Use collect or reduce with an associative operator.

Example

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        long n = 5_000_000L;

        long sequential = LongStream.rangeClosed(1, n).map(i -> i * 2).sum();
        long parallel = LongStream.rangeClosed(1, n).parallel().map(i -> i * 2).sum();

        System.out.println("cores          : " + Runtime.getRuntime().availableProcessors());
        System.out.println("common pool    : " + ForkJoinPool.getCommonPoolParallelism());
        System.out.println("sequential sum : " + sequential);
        System.out.println("parallel sum   : " + parallel);
        System.out.println("same answer    : " + (sequential == parallel));

        // Ordered terminal ops still hand back the original order.
        System.out.println("toList order   : " + IntStream.rangeClosed(1, 8).parallel().boxed().toList());

        // forEach makes no ordering promise in parallel. forEachOrdered does.
        StringBuilder sb = new StringBuilder();
        IntStream.rangeClosed(1, 8).parallel().forEachOrdered(sb::append);
        System.out.println("forEachOrdered : " + sb);
    }
}

Parallel is a tuning decision, not a speed switch. Benchmark it or leave it off.

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 Streams course, and every lesson in it is listed on the Streams contents page.