Abstract: The Fork/Join framework, located in J.U.C(java.util.Concurrent), is a framework provided in Java7 for the execution of parallel tasks. It can split large tasks into several small tasks, and finally summarize the results of each small task to obtain the final result.
This document is shared in huawei cloud community “high concurrency”. How to use the Fork/Join framework provided by Java7 to implement high concurrency programs? , author: Ice River.
Fork/Join framework
Located in J.U.C(java.util.Concurrent), is a framework provided in Java7 for performing parallel tasks, which can be broken up into several smaller tasks and the results of each smaller task can be summarized to get the final result. The basic idea is similar to that of MapReduce in Hadoop.
It uses the Work stealing algorithm (where a thread steals tasks from other queues to execute them), a work-stealing strategy used in parallel divide-and-conquer computing
Why do you need a job-stealing algorithm?
If we need to do a big task, we can put this task division for a number of mutually dependent child tasks, in order to reduce the competition between threads, then put these subtasks are different in the queue, and create a separate thread for each queue to perform the tasks in the queue, thread and queue one-to-one correspondence, For example, thread A handles tasks in queue A. However, some threads finish tasks in their queue first, while others have tasks in their queue. Instead of waiting, a finished thread can help another thread, so it steals a task from another thread’s queue to execute. In order to reduce the contention between the stolen thread and the stolen thread, a double-endian queue is usually used. The stolen thread always takes the task from the head of the double-endian queue, while the stolen thread always takes the task from the tail of the double-endian queue.
Advantages of job stealing algorithms
It makes full use of threads for parallel computation and reduces the contention between threads
Disadvantages of job stealing algorithms
In some cases, contention exists, such as when there is only one task in a two-ended queue. And this algorithm consumes more system resources, such as creating multiple threads and multiple double-ended queues.
Fork/Join framework limitations
For Fork/Join framework, when a task is waiting for it to use at the end of the Join operation to create the subtasks, carry out the task of worker threads to find other tasks not implemented, and began to carry out the tasks of these not taken, in this way, the threads run make full use of their time to improve the performance of the application. To achieve this goal, the tasks performed by the Fork/Join framework have some limitations, as shown below.
-
Tasks can only be synchronized using Fork and Join operations. If other synchronization mechanisms are used, the worker thread cannot perform other tasks while the synchronization operation is performed. For example, in the Fork/Join framework, if the task is put to sleep, the worker thread executing the task will not perform any other tasks during the sleep period.
-
In the Fork/Join framework, split tasks should not perform IO operations, such as reading and writing data files
-
Tasks cannot throw check exceptions and must do the necessary code to get them out
Core classes for the Fork/Join framework
At the heart of the Fork/Join framework are two classes: ForkJoinPool and ForkJoinTask. ForkJoinPool implements work stealing algorithms, manages worker threads, and provides information about the status and execution of tasks. ForkJoinTask provides a mechanism for performing Fork and Join operations on tasks.
The sample code
Example code is as follows:
package io.binghe.concurrency.example.aqs; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; @Slf4j public class ForkJoinTaskExample extends RecursiveTask<Integer> { public static final int threshold = 2; private int start; private int end; public ForkJoinTaskExample(int start, int end) { this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; Boolean canCompute = (end-start) <= threshold; if (canCompute) { for (int i = start; i <= end; i++) { sum += i; Int middle = (start + end) / 2; int middle = (start + end) / 2; ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle); ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end); // Execute the subtask lefttask.fork (); rightTask.fork(); Int leftResult = lefttask.join (); int rightResult = rightTask.join(); Sum = leftResult + rightResult; } return sum; } public static void main(String[] args) { ForkJoinPool forkjoinPool = new ForkJoinPool(); ForkJoinTaskExample task = new ForkJoinTaskExample(1, 100); // Execute a task Future<Integer> result = forkJoinPool.submit (task); try { log.info("result:{}", result.get()); } catch (Exception e) { log.error("exception", e); }}}Copy the code
Click to follow, the first time to learn about Huawei cloud fresh technology ~