Java ForkJoinPool Example


ForkJoinPool is a class in Java 8’s java.util.concurrent package that implements the ExecutorService interface. It’s a type of thread pool specifically designed to support the execution of tasks that can be broken down into smaller, more manageable subtasks, which can be executed in parallel to speed up the overall task execution. The ForkJoinPool class uses the fork/join framework to execute these subtasks in a way that balances the workload and minimizes waiting time.

The ForkJoinPool class provides a flexible and efficient way to execute large and complex tasks in parallel, especially when those tasks can be broken down into smaller, independent subtasks. It’s particularly useful for tasks that can benefit from divide-and-conquer algorithms, such as sorting, searching, and matrix operations. The ForkJoinPool class is used by the java.util.stream package to implement parallel streams in Java 8.

Example of using the ForkJoinPool in Java to find the maximum number in a large array:

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

class MaxTask extends RecursiveTask<Integer> {
  private static final int THRESHOLD = 10_000;
  private final int[] array;
  private final int start;
  private final int end;

  public MaxTask(int[] array, int start, int end) {
    this.array = array;
    this.start = start;
    this.end = end;
  }

  @Override
  protected Integer compute() {
    if (end - start <= THRESHOLD) {
      // base case: find the max directly
      int max = Integer.MIN_VALUE;
      for (int i = start; i < end; i++) {
        max = Math.max(max, array[i]);
      }
      return max;
    } else {
      // recursive case: split the task into two smaller tasks
      int mid = (start + end) / 2;
      MaxTask left = new MaxTask(array, start, mid);
      MaxTask right = new MaxTask(array, mid, end);
      left.fork();
      right.fork();
      int maxLeft = left.join();
      int maxRight = right.join();
      return Math.max(maxLeft, maxRight);
    }
  }
}

public class Main {
  public static void main(String[] args) {
    int[] array = getArray();
    ForkJoinPool pool = new ForkJoinPool();
    MaxTask task = new MaxTask(array, 0, array.length);
    int max = pool.invoke(task);
    System.out.println("The max of the array is: " + max);
  }
}

In this example, the MaxTask class extends the RecursiveTask class and overrides the compute method. The compute method implements the logic for finding the maximum number in the array. If the length of the task is less than or equal to the THRESHOLD, the maximum is found directly. If the length of the task is greater than the THRESHOLD, the task is split into two smaller tasks and each task is executed in parallel using the fork and join methods. The ForkJoinPool class is used to execute the MaxTask and retrieve the result.