WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Core Java · Expert · question 78 of 100

What is a ForkJoinPool in Java? How is it used?

📕 Buy this interview preparation book: 100 Core Java questions & answers — PDF + EPUB for $5

Java’s Fork/Join Framework is a concurrency model that is intended for parallel processing of CPU-bound operations. It allows developers to break down problems into smaller sub-problems, and distribute them across multiple threads and CPU cores for parallel execution. ForkJoinPool is the backbone of this framework and provides an implementation of the ExecutorService interface, which can be used to create and manage ForkJoinTask objects.

ForkJoinPool uses a work-stealing algorithm that allows idle threads to steal work from other threads that have more work to do. The ForkJoinPool maintains a queue of tasks that need to be executed, called the "work queue". When a thread finishes executing its own tasks, it looks for tasks in the work queue of other threads to "steal". This allows idle threads to keep themselves busy, minimizing the need for context switches and reducing the overhead of managing multiple threads.

Here’s an example of how to use the ForkJoinPool in Java:

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class MyTask extends RecursiveAction {
    private int[] arr;
    private int start, end;
    
    public MyTask(int[] arr, int start, int end) {
        this.arr = arr;
        this.start = start;
        this.end = end;
    }
    
    @Override
    protected void compute() {
        if (end - start <= 1000) {
            for (int i = start; i < end; i++) {
                arr[i] *= 2;
            }
        } else {
            int mid = (start + end) / 2;
            MyTask left = new MyTask(arr, start, mid);
            MyTask right = new MyTask(arr, mid, end);
            invokeAll(left, right);
        }
    }
    
    public static void main(String[] args) {
        int[] arr = new int[10000];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }
    
        ForkJoinPool pool = new ForkJoinPool();
        MyTask task = new MyTask(arr, 0, arr.length);
        pool.invoke(task);
    }
}

In this example, we define a task (MyTask) that doubles the elements of an array. If the array is larger than 1000 elements, it splits the task into two sub-tasks and invokes them in parallel using invokeAll(). If the array is smaller than or equal to 1000 elements, it simply doubles the elements sequentially.

We then create a ForkJoinPool and invoke the task on it using the invoke() method. The ForkJoinPool takes care of creating and managing threads and distributing the tasks across them.

ForkJoinPool is particularly useful for parallelizing recursive algorithms that divide a problem into smaller sub-problems, such as quicksort or mergesort. By dividing the problem into smaller sub-problems, it makes it easier to distribute the work across multiple threads and CPU cores, and potentially improve the performance of the algorithm.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Core Java interview — then scores it.
📞 Practice Core Java — free 15 min
📕 Buy this interview preparation book: 100 Core Java questions & answers — PDF + EPUB for $5

All 100 Core Java questions · All topics