liveBook · Manning

Parallel stream

As explained in 100 Java Mistakes and How to Avoid Them

A parallel stream is a Stream configured to process elements using multiple execution threads when the implementation permits.

A parallel stream processes elements using multiple execution threads when permitted. It changes the order in which operations may run, exposing Stream API violations that sequential execution can accidentally conceal. section 9.5

A reduction that fails in parallel

A List hash-code calculation using reduce(1, (x, y) -> x * 31 + y) can appear correct sequentially, even though the accumulator is neither associative nor compatible with the identity value. With parallelStream(), partial results combine in a different order and produce a wrong result. The outcome can also vary with processor count or ForkJoinPool parallelism. section 9.5

Avoid these parallel-stream failure modes:

  • Use reductions only when the accumulator is associative and has a valid identity; otherwise, sequential success is not evidence of correctness. section 9.5
  • Do not mutate shared collections from intermediate-operation functions; parallel execution can cause exceptions or lost data. section 9.2
  • Prefer partitioningBy() for partitioning data, and reserve peek() primarily for debugging because its function may be optimized away. section 9.2
List<String> list = List.of("a", "b", "c", "d");
System.out.println(list.hashCode());     #1
System.out.println(list.stream()
  .mapToInt(Objects::hashCode)
  .reduce(1, (x, y) -> x * 31 + y));    #2

Compare the standard List hash-code result with the reduce-based implementation that becomes invalid when parallelized. section 9.5

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains computation ordering, reduction contracts, concurrency consequences, and practical alternatives without developing parallel-stream internals.
Examples
Uses List hash-code reduction, concurrent collection mutation, partitioningBy(), and peek()-based trimming examples.
What it assumes
Assumes familiarity with Java streams, intermediate operations, terminal operations, reductions, and mutable collections.
What you can do after
Diagnose/debug with reduction contracts, execution-order changes, shared-state hazards, and ForkJoinPool parallelism experiments.
How it connects
Connects parallel streams with Stream API reductions, associativity, identity values, side effects, partitioningBy(), and ForkJoinPool parallelism.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.