When a task is very large it tries to split it, and Java7 provides a ForkJoin framework for splitting tasks.

ForkJoin introduction

ForkJoin is a multi-threaded parallel execution framework that uses CPU resources and improves program efficiency by dividing a large task into several smaller tasks.

ForkJoin consists of two main steps:

Fork: The first step is to split a large task into smaller tasks. If the smaller tasks are still too large, the split will continue until they are small enough.

Join: The results obtained after each task is executed are summarized and the final result is returned.

The main process of task segmentation and merger is as follows:

Several key classes

ForkJoin requires two definitions, one for tasks and one for task management, a class to represent a task and a manager to manage the execution of the task.

ForkJoinTask indicates a task. ForkJoinTask is an abstract class that has two subclasses, RecursiveTask and RecursiveAction. RecursiveTask is used for tasks that return results. RecursiveAction is used for tasks that do not return results.

ForkJoinPool is a task management class that ForkJoinTask relies on to execute its tasks, and ForkJoinPool supports task stealing because ForkJoinTask tasks are placed in queues maintained by the current worker thread. When all the queues in the worker thread are completed, it will fetch tasks from other worker threads’ queues to execute. Task stealing makes full use of thread resources to speed up parallel computing.

A simple example

Let’s start with an example of RecursiveTask that returns a result, as shown below:

The main process is to customize an inheritance to a RecursiveTask and then implement compute, which determines whether the task needs to be split again and how to assemble the result after the split. If the difference between the two numbers is too large, the task will be split. Then the sub-task will call the fork method to add itself to the work queue, call the join method to get the result, and finally merge the result.

The test code for RecursiveAction looks like this:

A RecursiveAction is similar to a RecursiveTask, except that instead of waiting for a result, a ForkJoinPool RecursiveAction attempts to wait for a result by calling the awaitTermination method.

conclusion

ForkJoin relies on a ForkJoinTask to represent a task. ForkJoinTask relies on a ForkJoinPool to perform a task. A ForkJoinPool creates a worker thread to perform a task. The task is executed by calling the compute method of ForkJoinTask RecursiveTask, RecursiveAction.

The compute method needs to be implemented by ourselves. In compute, we define how to split the method and assemble the result. After the split, ForkJoinTask forks the task into the queue of the current worker thread.

When a worker thread finishes executing a task, it retrieves the task from the queue to continue executing it. When there are no tasks in the queue, it retrieves the task from another worker thread’s queue.

Java programmer daily study notes, such as understanding the wrong welcome to exchange discussion!