Calculate a Sum Using Parallel Streams in Java
Problem
A parallel stream splits its work across several threads from the common ForkJoinPool and combines the partial results.
Sum the numbers from 1 to 10,000,000 sequentially and in parallel, and check both totals against the formula n(n + 1)/2.
Java Program
import java.util.stream.LongStream;
public class ParallelStreamSum {
public static void main(String[] args) {
long n = 10_000_000;
long sequential = LongStream.rangeClosed(1, n).sum();
long parallel = LongStream.rangeClosed(1, n).parallel().sum(); // split across CPU cores
System.out.println("Sequential sum: " + sequential);
System.out.println("Parallel sum: " + parallel);
System.out.println("Same result: " + (sequential == parallel));
System.out.println("Formula check: " + n * (n + 1) / 2);
}
}Output
Core Logic
Calling parallel() changes how the stream runs, not what it computes — for an associative operation like addition, the result is identical.
- 1
LongStream.rangeClosed(1, n).sum()adds the numbers on one thread. - 2
.parallel()splits the range into chunks summed on several threads, then adds the chunk totals. - 3
longis needed, because the total exceeds theintrange. - 4The formula n(n + 1)/2 confirms the answer.
Key Point: Parallel streams pay off only for large, CPU-heavy, easily split work; for small lists the thread coordination costs more than it saves.
Why: Every number is added once in total; parallelism divides that work across cores rather than reducing it.
Key Concepts
Approach 2: Keeping Order in Parallel
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ParallelStreamOrder {
public static void main(String[] args) {
List<Integer> squares = IntStream.rangeClosed(1, 8)
.parallel()
.map(x -> x * x)
.boxed()
.collect(Collectors.toList()); // collect keeps the encounter order, even in parallel
StringBuilder ordered = new StringBuilder();
IntStream.rangeClosed(1, 8).parallel()
.forEachOrdered(x -> ordered.append(x).append(' ')); // forEach would not guarantee order
System.out.println("Squares: " + squares);
System.out.println("forEachOrdered: " + ordered.toString().trim());
}
}
Output
Core Logic
Parallel streams may process elements in any order, but collect and forEachOrdered still respect the original order.
- 1
mapruns on several threads, yetcollect(toList())returns squares in order 1 to 8. - 2
forEachOrderedprocesses elements in their original order. - 3Plain
forEachon a parallel stream would print them in an unpredictable order.
Key Point: If order matters, use forEachOrdered or collect first — and remember that enforcing order can cancel much of the parallel speed-up.
Why: Each element is processed once and stored in the result list.
Key Concepts
Interview Questions
Which thread pool do parallel streams use?
The shared ForkJoinPool.commonPool(), whose size defaults to one less than the number of CPU cores.
Why is a parallel stream risky with shared mutable state?
Several threads may update the same variable at once, causing lost updates. Use reductions or collectors instead of writing to shared collections.