java.util.concurrent.ForkJoinPool Example (original) (raw)

In this example, we shall be demonstrating the use of java.util.concurrent.ForkJoinPool Class. This class was introduced in Java 7.

The java.util.concurrent.ForkJoinPool Class implements java.util.concurrent.Executor and java.util.concurrent.ExecutorService interfaces. This class works on divide-and-conquer policy. Each major subtask is divided into a number of sub-tasks and a new thread is spawned for each new sub-task. Recursion is the most popular strategy for dividing the work. Once sub-tasks are completed(conquered), their results are joined together and the final result is returned.

Tip
Unlike other implementations of ExecutorService, java.util.concurrent.ForkJoinPool need not be explicitly shut-down as all threads in this pool are started as Daemon Threads.

The sub-tasks created are usually sub-classes of either RecursiveAction or RecursiveTask abstract classes. The task class have to override the compute method. Upon invocation of the task the compute method is invoked. The difference between the two classes is that the compute method of RecursiveTask<V> Class returns the result of computation from the sub-tasks. (analogous to the Callable)

1. Pseudo-code for Fork/Join high-level view

Result solve(Problem problem) { if (problem is smaller than threshhold) solve the problem sequentially else { split the task into sub-tasks fork new subtasks to solve each part join all subtasks to get the sub-results combine the sub-results to get the final result. } }

We will implement the RecursiveTask<V> Class and create the tasks for searching a given folder and its sub-folders, for a given string in the name of the files. The tasks are implemented in its compute() method. The main task will spawn other tasks recursively, i.e. one task for each sub-folder in the given main folder. The After all the sub-tasks are forked, we shall join them to get the final List of files(file names). The ForkJoinPoolDemo class then creates a ForkJoinPool object, which will start executing the main task.

In case, we do not specify any argument while creating the object of ForkJoinPool the size of pool is equivalent to Runtime.getRuntime().availableProcessors() i.e. the available number of processors(counting the ability of hyper threading by processors) on the machine.

SearchDirectory.java:

package com.javacodegeeks.examples.concurrent;

import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.RecursiveTask;

/**

}

ForkJoinPoolExample.java:

package com.javacodegeeks.examples.concurrent;

import java.util.List; import java.util.concurrent.ForkJoinPool;

/**

2. Application of ForkJoinPool in Existing Core Java Packages

3. Conclusion

Thus we have studied the working of ForkJoinPool in Java and its benefits over other ExecutorService implementations.

Photo of Chandan Singh

Chandan holds a degree in Computer Engineering and is a passionate software programmer. He has good experience in Java/J2EE Web-Application development for Banking and E-Commerce Domains.