Java / Java Concurrency and Multi Threading in Java 17 and Java 21 Interview questions
Explain the execution flow of a parallel stream operation?
Calling .parallelStream() or .stream().parallel() doesn't run your pipeline on one thread per element; it decomposes the source into chunks and submits the work to the common ForkJoinPool.
flowchart TD A[Source: e.g. a List] --> B[Spliterator splits source into chunks] B --> C[Chunks recursively forked as ForkJoinTask subtasks] C --> D[Common ForkJoinPool workers process chunks in parallel] D --> E[Partial results combined pairwise] E --> F[Final terminal result, e.g. sum or collected list]
Internally, the stream's Spliterator recursively splits the source into balanced chunks, each becomes a ForkJoinTask, and those tasks run on the JVM-wide common ForkJoinPool, using the same fork/join, work-stealing mechanism used by RecursiveTask. Intermediate operations like map and filter are applied lazily per chunk, and the terminal operation's results are combined pairwise, for example via the combiner function passed to collect(), until a single final result remains.
Because it uses the shared common pool by default, a long-running blocking call inside a parallel stream can starve every other unrelated parallel stream and any CompletableFuture that also relies on the common pool elsewhere in the JVM. For CPU-bound, evenly splittable work like arithmetic over an array-backed list, this scales well; for small collections, I/O-bound work, or sources like a LinkedList that split poorly, the fork/join overhead can make a parallel stream slower than a plain sequential one.
More Related questions...