How to configure custom ThreadPool for Java 8 Stream API parallel operations

Carvia Tech | December 03, 2019 | 2 min read | 11 views | Multithreading and Concurrency

There are two approaches to configure custom sized thread pool for Java 8 parallel stream operations - configure default common pool and running parallel stream operation inside ForkJoinPool.

Java does not provide any direct mechanism to control the number of threads and ThreadPool used by parallel() method in stream API, but there are two indirect way to configure the same.

Configure default Common Pool

Its documented that parallel() method utilizes the common pool available per classloader per jvm, and we have a mechanism to control the configuration of that default common pool using below 3 System properties


The parallelism level, a non-negative integer


The class name of a ForkJoinPool.ForkJoinWorkerThreadFactory


The class name of a Thread.UncaughtExceptionHandler

For example, set the System property before calling the parallel stream

Changing the default common pool size JVM wide
public class CustomCommonPoolSize {
    public void testParallelOperation() {
        long start = System.currentTimeMillis();
        IntStream s = IntStream.range(0, 20);
        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");
        s.parallel().forEach(i -> {
            try {
            } catch (Exception ignore) {}
            System.out.print((System.currentTimeMillis() - start) + " ms");
        System.out.println("\nOverall time consumed: "+ (System.currentTimeMillis() - start)+" ms");
Program output
192 192 192 192 192 192 192 192 192 192 192 192 192 192 192 192 192 192 192 192
Overall time consumed: 193 ms

Se see that all 20 tasks run in parallel and this the overall time is just 193 ms, even if individual task was taking 192ms each.

Run the parallel() operation inside a custom ForkJoinPool

There actually is a trick how to execute a parallel operation in a specific fork-join pool. If you execute it as a task in a fork-join pool, it stays there and does not use the common one. The trick is based on ForkJoinTask.

Fork documentation which specifies:

Arranges to asynchronously execute this task in the pool the current task is running in, if applicable, or using the ForkJoinPool.commonPool() if not in ForkJoinPool()

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;

import static java.lang.Math.sqrt;
import static;

class StreamExampleJava8 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = new ForkJoinPool(4); // Configure the number of threads
        forkJoinPool.submit(() -> IntStream.range(1, 1_000_000)

    private static boolean isPrime(long n) {
        return n > 1 && IntStream.rangeClosed(2, (int) sqrt(n)).noneMatch(divisor -> n % divisor == 0);

In above code block, fork join pool will create 4 threads and run the parallel operations inside this custom fork join pool.

That’s all for this tutorial.

Top articles in this category:
  1. How will you increment each element of an Integer array, using parallel operation
  2. How to implement Thread pool in Java without executor framework
  3. How will you implement your custom threadsafe Semaphore in Java
  4. Diamond Problem of Inheritance in Java 8
  5. What is Deadlock in Java? How to troubleshoot and how to avoid deadlock
  6. What is left shift right shift and unsigned rght shift operator in Java
  7. Http download using Java NIO FileChannel

Find more on this topic:
Core Java image
Core Java

Core Java - OOP Concepts, Garbage Collection, Multi-threading, Collections Framework, Java 8 Features, Lambda Functions, Streams.

Last updated 1 week ago

Recommended books for interview preparation:

This website uses cookies to ensure you get the best experience on our website. more info