Modern computers are already in the direction of multi-CPU, even ordinary PCs, even now smartphones, multicore processors have been widely used. In the future, the core number of processors will grow more and more.

Although the multi-core CPUs on the hardware are already mature, many applications are not prepared for this multicore CPU and therefore do not take advantage of the performance benefits of multicore CPUs.

In order to make full use of the performance advantages of multi-CPU and multi-core CPU, the software system of soft-base should be able to fully "excavate" the computing power of each CPU and never let a CPU be in "idle" state. To do this, consider splitting a task into multiple "small tasks" and putting multiple "small tasks" into parallel execution on multiple processor cores. When more than one "small task" executes, the results are merged together.

As shown in the following:

**The first step is to split the task. First we need to have a fork class to divide the large task into sub-tasks, it is possible that the subtasks are still very large, so it is necessary to continue to split, until the split sub-task is small enough.**

**The second step executes the task and merges the results. Split subtasks are placed in a double-ended queue, and several boot threads get task execution from the double-ended queue, respectively. The results of the subtasks are uniformly placed in a queue, starting a thread to take the data from the queue, and then merging the data.**

Java provides forkjoinpool to support splitting a task into multiple "small task" parallel computations, and then synthesizing the results of multiple "small tasks" into the overall calculation.

Forkjoinpool is an implementation class for Executorservice and is therefore a special thread pool. Forkjoinpool provides the following two commonly used constructors.

- Public forkjoinpool (int parallelism): Create a containing parallelism a parallel thread. Forkjoinpool
- Public Forkjoinpool (): To The return value of Runtime.getruntime (). Availableprocessors () as parallelism to create Forkjoinpool

After creating the Forkjoinpool instance, you can forkjoinpool the submit (forkjointask<t> Task) or Invoke (Forkjointask<t > Task) to perform the specified task. where Forkjointask represents a task that can be parallel and merged. Forkjointask is an abstract class that has two abstract subclasses: Recursiveaction and Recursivetask.

- Recursivetask represents a task with a return value
- Recursiveaction represents a task that has no return value.

First,recursiveaction

The following is an example of a large task with no return value, which describes the use of recursiveaction.

The big task is to print a value of 0-200.

The small task is: only 50 values can be printed at a time.

Import Java.util.concurrent.forkjoinpool;import Java.util.concurrent.recursiveaction;import Java.util.concurrent.timeunit;//recursiveaction is an abstract subclass of Forkjointask, Task class Printtask extends recursiveaction with no return value {//each "small task" prints a maximum of 50 digits private static final int MAX = 50;private int start;private int end; Printtask (int start, int end) {This.start = Start;this.end = end;} @Overrideprotected void Compute () {///when the value of End-start is less than MAX, start printing if ((End-start) < MAX) {for (int i = start; I < end; i++) {System.out.println (Thread.CurrentThread (). GetName () + "I value:" + i);}} else {//Divide large task into two small task int middle = (start + end)/2; Printtask left = new Printtask (start, middle); Printtask right = new Printtask (middle, end);//parallel execution of two small tasks left.fork (); Right.fork ();}} public class Forkjoinpooltest {/** * @param args * @throws Exception */public static void Main (string[] args) throws Excep tion {//Create a Runtime.getruntime (). Availableprocessors () return value as the number of parallel threads forkjoinpoolforkjoinpool Forkjoinpool = new Forkjoinpool ();//Submit a biodegradable PRInttask Task Forkjoinpool.submit (new Printtask (0, +)), Forkjoinpool.awaittermination (2, timeunit.seconds);//block current thread until All tasks in Forkjoinpool execute end//close thread pool Forkjoinpool.shutdown ();}}

The results of the operation are as follows:

I value of forkjoinpool-1-worker-2: I value of 75forkjoinpool-1-worker-2:76forkjoinpool-1-worker-2 I value : I value of 77forkjoinpool-1-worker-2: I value of 78forkjoinpool-1-worker-2:79forkjoinpool-1-worker-2 I value : I value of 80forkjoinpool-1-worker-2: I value of 81forkjoinpool-1-worker-2:82forkjoinpool-1-worker-2 I value : I value of 83forkjoinpool-1-worker-2: I value of 84forkjoinpool-1-worker-2:85forkjoinpool-1-worker-2 I value : I value of 86forkjoinpool-1-worker-2: I value of 87forkjoinpool-1-worker-2:88forkjoinpool-1-worker-2 I value : I value of 89forkjoinpool-1-worker-2: I value of 90forkjoinpool-1-worker-2:91forkjoinpool-1-worker-2 I value : I value of 92forkjoinpool-1-worker-2: I value of 93forkjoinpool-1-worker-2:94forkjoinpool-1-worker-2 I value : I value of 95forkjoinpool-1-worker-2: I value of 96forkjoinpool-1-worker-2:97forkjoinpool-1-worker-2 I value : I value of 98forkjoinpool-1-worker-2: I value of 99forkjoinpool-1-worker-2:50forkjoinpool-1-worker-2 I value : I value of 51forkjoinpool-1-worker-2: I value of 52forkjoinpool-1-worker-2:53forkjoinpool-1-worker-2 I value : I value of 54forkjoinpool-1-worker-2: I value of 55forkjoinpool-1-worker-2:56forkjoinpool-1-worker-2 I value : 57forkjoinpool-1-worker-2 I value: 58forkjoinpool-1I value of-worker-2: I value of 59forkjoinpool-1-worker-2: I value of 60forkjoinpool-1-worker-2:61forkjoinpool-1-worker-2 I value : I value of 62forkjoinpool-1-worker-2: I value of 63forkjoinpool-1-worker-2:64forkjoinpool-1-worker-2 I value : I value of 65forkjoinpool-1-worker-2: I value of 66forkjoinpool-1-worker-2:67forkjoinpool-1-worker-2 I value : I value of 68forkjoinpool-1-worker-2: I value of 69forkjoinpool-1-worker-1:175forkjoinpool-1-worker-1 I value : I value of 176forkjoinpool-1-worker-1: I value of 177forkjoinpool-1-worker-1:178forkjoinpool-1-worker-1 I value : I value of 179forkjoinpool-1-worker-1: I value of 180forkjoinpool-1-worker-1:181forkjoinpool-1-worker-1 I value : I value of 182forkjoinpool-1-worker-1: I value of 183forkjoinpool-1-worker-1:184forkjoinpool-1-worker-1 I value : I value of 185forkjoinpool-1-worker-1: I value of 186forkjoinpool-1-worker-1:187forkjoinpool-1-worker-1 I value : I value of 188forkjoinpool-1-worker-1: I value of 189forkjoinpool-1-worker-1:190forkjoinpool-1-worker-1 I value : I value of 191forkjoinpool-1-worker-1: I value of 192forkjoinpool-1-worker-1:193forkjoinpool-1-worker-1 I value : 194forkjoinpool-1-worker-1 I value: 195forkjoinpool-1-worker-1 I value: 196forkjoinpool-1-worker-1 I value: 197ForkJI value of oinpool-1-worker-1: I value of 198forkjoinpool-1-worker-1:199forkjoinpool-1-worker-1 I value : I value of 150forkjoinpool-1-worker-1: I value of 151forkjoinpool-1-worker-1:152forkjoinpool-1-worker-1 I value : I value of 153forkjoinpool-1-worker-1: I value of 154forkjoinpool-1-worker-1:155forkjoinpool-1-worker-1 I value : I value of 156forkjoinpool-1-worker-1: I value of 157forkjoinpool-1-worker-1:158forkjoinpool-1-worker-1 I value : I value of 159forkjoinpool-1-worker-1: I value of 160forkjoinpool-1-worker-1:161forkjoinpool-1-worker-1 I value : I value of 162forkjoinpool-1-worker-1: I value of 163forkjoinpool-1-worker-1:164forkjoinpool-1-worker-1 I value : I value of 165forkjoinpool-1-worker-1: I value of 166forkjoinpool-1-worker-1:167forkjoinpool-1-worker-1 I value : I value of 168forkjoinpool-1-worker-1: I value of 169forkjoinpool-1-worker-1:170forkjoinpool-1-worker-1 I value : I value of 171forkjoinpool-1-worker-1: I value of 172forkjoinpool-1-worker-1:173forkjoinpool-1-worker-1 I value : I value of 174forkjoinpool-1-worker-1: I value of 125forkjoinpool-1-worker-1:126forkjoinpool-1-worker-1 I value : I value of 127forkjoinpool-1-worker-1:128forkjoinpool-1-worker-1 I value: 129forkjoinpool-1-worker-1 I value: 130ForkJoinPool-1-I value of worker-1: I value of 131forkjoinpool-1-worker-1: I value of 132forkjoinpool-1-worker-1:133forkjoinpool-1-worker-1 I value : I value of 134forkjoinpool-1-worker-1: I value of 135forkjoinpool-1-worker-1:136forkjoinpool-1-worker-1 I value : I value of 137forkjoinpool-1-worker-1: I value of 138forkjoinpool-1-worker-1:139forkjoinpool-1-worker-1 I value : I value of 140forkjoinpool-1-worker-1: I value of 141forkjoinpool-1-worker-1:142forkjoinpool-1-worker-1 I value : I value of 143forkjoinpool-1-worker-1: I value of 144forkjoinpool-1-worker-1:145forkjoinpool-1-worker-1 I value : I value of 146forkjoinpool-1-worker-1: I value of 147forkjoinpool-1-worker-1:148forkjoinpool-1-worker-1 I value : I value of 149forkjoinpool-1-worker-1: I value of 100forkjoinpool-1-worker-1:101forkjoinpool-1-worker-1 I value : I value of 102forkjoinpool-1-worker-1: I value of 103forkjoinpool-1-worker-1:104forkjoinpool-1-worker-1 I value : I value of 105forkjoinpool-1-worker-1: I value of 106forkjoinpool-1-worker-1:107forkjoinpool-1-worker-1 I value : I value of 108forkjoinpool-1-worker-1: I value of 109forkjoinpool-1-worker-1:110forkjoinpool-1-worker-1 I value : I value of 111forkjoinpool-1-worker-1: I value of 112forkjoinpool-1-worker-1:113forkjoinpool-1-worker-1 IValue: 114forkjoinpool-1-worker-1 I value: 115forkjoinpool-1-worker-1 I value: 116forkjoinpool-1-worker-1 I value : I value of 117forkjoinpool-1-worker-1: I value of 118forkjoinpool-1-worker-1:119forkjoinpool-1-worker-1 I value : I value of 120forkjoinpool-1-worker-1: I value of 121forkjoinpool-1-worker-1:122forkjoinpool-1-worker-1 I value : I value of 123forkjoinpool-1-worker-1: I value of 124forkjoinpool-1-worker-1:25forkjoinpool-1-worker-1 I value : I value of 26forkjoinpool-1-worker-1: I value of 27forkjoinpool-1-worker-1:28forkjoinpool-1-worker-1 I value : I value of 29forkjoinpool-1-worker-1: I value of 30forkjoinpool-1-worker-1:31forkjoinpool-1-worker-1 I value : I value of 32forkjoinpool-1-worker-1: I value of 33forkjoinpool-1-worker-1:34forkjoinpool-1-worker-1 I value : I value of 35forkjoinpool-1-worker-1: I value of 36forkjoinpool-1-worker-1:37forkjoinpool-1-worker-1 I value : I value of 38forkjoinpool-1-worker-1: I value of 39forkjoinpool-1-worker-1:40forkjoinpool-1-worker-1 I value : I value of 41forkjoinpool-1-worker-1: I value of 42forkjoinpool-1-worker-1:43forkjoinpool-1-worker-1 I value : I value of 44forkjoinpool-1-worker-1: I value of 45forkjoinpool-1-worker-1:46forkjoinpool-1-worker-1 I value : 47forkjoinpool-1-worker-1 I value: 4I value of 8forkjoinpool-1-worker-1: I value of 49forkjoinpool-1-worker-1:0forkjoinpool-1-worker-1 I value : I value of 1forkjoinpool-1-worker-1: I value of 2forkjoinpool-1-worker-1:3forkjoinpool-1-worker-1 I value : I value of 4forkjoinpool-1-worker-1: I value of 5forkjoinpool-1-worker-1:6forkjoinpool-1-worker-1 I value : I value of 7forkjoinpool-1-worker-1: I value of 8forkjoinpool-1-worker-1:9forkjoinpool-1-worker-1 I value : I value of 10forkjoinpool-1-worker-1: I value of 11forkjoinpool-1-worker-1:12forkjoinpool-1-worker-1 I value : I value of 13forkjoinpool-1-worker-1: I value of 14forkjoinpool-1-worker-1:15forkjoinpool-1-worker-1 I value : I value of 16forkjoinpool-1-worker-1: I value of 17forkjoinpool-1-worker-1:18forkjoinpool-1-worker-1 I value : I value of 19forkjoinpool-1-worker-1: I value of 20forkjoinpool-1-worker-1:21forkjoinpool-1-worker-1 I value : I value of 22forkjoinpool-1-worker-1: I value of 23forkjoinpool-1-worker-1:24forkjoinpool-1-worker-2 I value : I value of 70forkjoinpool-1-worker-2: I value of 71forkjoinpool-1-worker-2:72forkjoinpool-1-worker-2 I value : 73forkjoinpool-1-worker-2 I value: 74

From the above results, Forkjoinpool started two threads to perform this print task because the author's computer CPU is dual-core. Not only that, the reader can see that the program printed 0-199 of these 200 numbers, but not continuous printing, this is because the program to decompose the print task, the decomposition of the task will be executed in parallel, so do not sequentially from 0 to 199.

Second, Recursivetask

The following is an example of a large task with a return value, which describes the use of recursivetask .

The big task is: Calculate the and of the random 100 numbers.

Small task is: only 20 numeric values at a time.

Import Java.util.random;import Java.util.concurrent.forkjoinpool;import Java.util.concurrent.future;import Java.util.concurrent.recursivetask;//recursivetask is an abstract subclass of Forkjointask, with a return value of the task class Sumtask extends Recursivetask <Integer> {//each "small task" prints a maximum of 50 digits private static final int MAX = 20;private int arr[];p rivate int start;private int end; Sumtask (int arr[], int start, int end) {This.arr = Arr;this.start = Start;this.end = end;} @Overrideprotected Integer Compute () {int sum = 0;//when the value of End-start is less than MAX, start printing if ((End-start) < MAX) {for (int i = STA Rt I < end; i++) {sum + = Arr[i];} return sum;} else {System.err.println ("===== task decomposition ======");//Break the big task into two small tasks int middle = (start + end)/2; Sumtask left = new Sumtask (arr, start, middle); Sumtask right = new Sumtask (arr, middle, end);//parallel execution of two small tasks left.fork (); Right.fork ();//combine the results of two small tasks together to return Left.join () + Right.join ();}}} public class ForkJoinPoolTest2 {/** * @param args * @throws Exception */public static void Main (string[] args) throws Exce Ption {int arr[] = new INT[100]; Random random = new random (); int total = 0;//Initializes 100 numeric elements for (int i = 0; i < arr.length; i++) {int temp = Random.nextin T (100);//Assign a value to the array element and add the value of the element to total + = (Arr[i] = temp) in the sum System.out.println ("sum at initialization =" + total);//create contains Runtime.getruntime (). Availableprocessors () Returns the value as a number of parallel threads of forkjoinpoolforkjoinpool Forkjoinpool = new Forkjoinpool ();//Submit a biodegradable Printtask task future<integer> Future = Forkjoinpool.submit (new Sumtask (arr, 0,arr.length)); System.out.println ("Calculated sum =" + Future.get ());//close thread pool Forkjoinpool.shutdown ();}}

The calculation results are as follows:

Sum at initialization =4283===== task decomposition =========== task Decomposition =========== task Decomposition =========== task Decomposition =========== task Decomposition =========== task decomposition =========== Task decomposition ====== the sum computed =4283

From the above results,forkjoinpool the task decomposition 7 times, the program through the Sumtask calculated results, and the initialization of the array when the sum of the statistics is equal, which indicates that the results of the calculation is normal.

Readers also refer to the following articles to deepen their understanding of Forkjoinpool :

http://www.infoq.com/cn/articles/fork-join-introduction/

http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/

==================================================================================================

**Ouyangpeng welcome reprint, sharing with people is the source of progress!**

**Reprint please keep the original address : Http://blog.csdn.net/ouyang_peng**

==================================================================================================

My Java Development Learning journey------>java Use the Fork/join framework to perform tasks in parallel