Java Multi-thread Forkjoinpool

Source: Internet
Author: User

Turn https://www.cnblogs.com/lixuwu/p/7979480.html

Read Catalogue

    • Use

Background: The advantage of Forkjoinpool is that it can take advantage of multi-CPU, multi-core CPU, split a task into multiple "small tasks", put multiple "small tasks" into parallel execution on multiple processor cores, and then merge the results of the multiple "small tasks" after the completion of the execution. This thought is worth learning.

The main reference is "crazy Java Handout"

Go back to the top of use

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

Forkjoinpool is an implementation class for Executorservice and is therefore a special thread pool.

Usage: Once you have created the Forkjoinpool instance, you can call Forkjoinpool's submit (forkjointask<t> Task) or invoke (forkjointask<t> Task) method to perform the specified task.

where Forkjointask represents a task that can be parallel and merged. Forkjointask is an abstract class, and it has two abstract subclasses: Recusiveaction and Recusivetask. where Recusivetask represents a task with a return value, and recusiveaction represents a task that does not return a value.

The following UML class diagram shows the relationship between Forkjoinpool and Forkjointask:

Example

As an example of a "big task" (a simple low-print 1~300 value) that does not return a value, the program splits a "big task" into multiple "small tasks" and gives the task to Forkjoinpool to perform

/** * Project name:spring0725 * File Name:ForkJoinPoolAction.java * Package Name:work1201.basic * date:2017 year December 4 afternoon 2:26:5 5 * Copyright (c) 2017, Shenzhen financial Electronic Settlement Center all rights Reserved. **/package Work1201.basic;import Java.util.concurrent.forkjoinpool;import java.util.concurrent.RecursiveAction; Import java.util.concurrent.timeunit;/** * classname:forkjoinpoolaction <br/> * Function: Use Forkjoinpool to complete a task of staging execution * Simple printing of 0-300 values.       Implementing parallel execution with multithreading * date:2017 December 4 pm 2:26:55 <br/> * @author Prd-lxw * @version 1.0 * @since JDK 1.7 * @see */public class Forkjoinpoolaction {public static void main (string[] args) throws exception{Printtask T        Ask = new Printtask (0, 300);        Create an instance and perform a split task Forkjoinpool pool = new Forkjoinpool ();         Pool.submit (Task);        Thread blocking, waiting for all tasks to complete pool.awaittermination (2, timeunit.seconds);    Pool.shutdown (); }}/** * Classname:printtask <br/> * Function: Inherits Recursiveaction to achieve "biodegradable" tasks. * date:2017 year December 4 afternoon5:17:41 <br/> * * @author Prd-lxw * @version 1.0 * @since JDK 1.7 */class printtask extends recursiveaction{priv ATE static final int THRESHOLD = 50;    A maximum of 50 digits private int start can be printed;            private int end;        Public printtask (int start, int end) {super ();        This.start = start;    This.end = end; } @Override protected void Compute () {if (End-start < THRESHOLD) {for (int i=start;i&l            t;end;i++) {System.out.println (Thread.CurrentThread (). GetName () + "I value:" +i);            }}else {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 (); }            }    }

Execution Result:

I value of forkjoinpool-1-worker-1: I value of 262forkjoinpool-1-worker-7:75forkjoinpool-1-worker-7 I value: 76forkjoinpool-1-worker-5 I value: 225For I value of kjoinpool-1-worker-3: I value of 187forkjoinpool-1-worker-6:150forkjoinpool-1-worker-6 I value: 151forkjoinpool-1-worker-6 I value: 152Fork I value of joinpool-1-worker-6: The I value of 153forkjoinpool-1-worker-6:154 ...

Because my computer is a i7 processor, a total of 8 CPUs, observe the name of the thread can be found, 8 CPUs are running.

An array element of length 100 is accumulated by the return value of Recursivetask.

/** * Project name:spring0725 * File Name:ForJoinPollTask.java * Package Name:work1201.basic * date:2017 year December 4 5:41:46 * Copyright (c) 2017, Shenzhen financial Electronic Settlement Center all rights Reserved. **/package Work1201.basic;import Java.util.random;import Java.util.concurrent.forkjoinpool;import Java.util.concurrent.future;import java.util.concurrent.recursivetask;/** * Classname:forjoinpolltask <br/> *    Function: Accumulates an element value with a length of 100 * date:2017 December 4 pm 5:41:46 <br/> * @author Prd-lxw * @version 1.0 * @since        JDK 1.7 * @see */public class Forjoinpolltask {public static void main (string[] args) throws Exception {        int[] arr = new int[100];        Random random = new random ();        int total = 0;            Initializes 100 array elements for (int i=0,len = arr.length;i<len;i++) {int temp = Random.nextint (20);        Assigns a value to an array element and adds the value of the element to the sum in total + = (arr[i]=temp);        } System.out.println ("Initialize the sum of the arrays:" +total); Sumtask task = new Sumtask (arr, 0,ARR.LENGTH);//Create a universal pool, this is the function provided by jdk1.8 forkjoinpool pool = Forkjoinpool.commonpool (); future<integer> future = Pool.submit (Task);        Commit the decomposed Sumtask task System.out.println ("Multithreaded execution Result:" +future.get ()); Pool.shutdown ();  Turn off thread pool}}/** * Classname:sumtask <br/> * Function: Inherit abstract class Recursivetask, by returning the result, to implement the multi-threaded fragment of the array plus * Recursivetask with return value * date:2017 December 4 pm 6:08:11 <br/> * * @author Prd-lxw * @version 1.0 * @since JDK 1.7 */class  Sumtask extends recursivetask<integer>{private static final int THRESHOLD = 20;//each small task accumulates up to 20 number of private int    Arry[];    private int start;            private int end;     /** * Creates a new instance of Sumtask. * Accumulate Arry array from start to end * @param arry * @param start * @param end */Public Sumtask (int[] arry, int start        , int end) {super ();        This.arry = Arry;        This.start = start;    This.end = end; } @Override protected Integer compute () {int sum = 0;                When the difference between end and start is less than THRESHOLD, start the actual cumulative if (End-start <threshold) {for (int i= start;i<end;i++) {            Sum + = Arry[i];        } return sum;            }else {//when the difference between end and start is greater than threshold, that is, to accumulate more than 20 times, the large task is decomposed into a small task int middle = (start+ end)/2;            Sumtask left = new Sumtask (Arry, start, middle);            Sumtask right = new Sumtask (Arry, middle, end);            Parallel execution of two small tasks left.fork ();            Right.fork ();        Combine the results of two small tasks to return Left.join () +right.join (); }            }    }

Execution Result:

Initialize the sum of the arrays: 1008 multi-threaded execution results: 1008

Analysis

A new thread pool has been introduced in Java 7: Forkjoinpool.

Like Threadpoolexecutor, it also implements the executor and Executorservice interfaces. It uses an infinite queue to hold the tasks that need to be performed, and the number of threads is passed through the constructor, and if no number of threads are passed into the constructor, the number of CPUs available to the current computer is set to the number of threads as the default.

Forkjoinpool is mainly used to solve problems by using the divide-and-conquer method (Divide-and-conquer algorithm). Typical applications such as fast sorting algorithms.

The point here is that Forkjoinpool needs to use a relatively small number of threads to handle a lot of tasks.

For example, to sort 10 million data, the task is divided into two 5 million sort tasks and a merge task for both sets of 5 million data. And so, for 5 million of the data will be the same split processing, to the end will set a threshold to specify when the size of the data to stop such a split processing. For example, when the number of elements is less than 10 o'clock, the splits are stopped, instead they are sorted using the insert sort.

So in the end, all of the tasks will be about 2000000+. The point of the problem is that, for a task, it can be executed only when all of its subtasks have been completed.

So when using Threadpoolexecutor, there is a problem with splitting, because the thread in the Threadpoolexecutor is unable to add another task in the task queue and wait until the task is complete before continuing. When using Forkjoinpool, it is possible for the thread to create a new task and suspend the current task, at which point the thread can select the child task execution from the queue.

The key to the above procedure is the fork () and join () methods. In the thread used by Forkjoinpool, an internal queue is used to manipulate the tasks that need to be performed and the subtasks to ensure their order of execution.

So what are the differences in performance when using Threadpoolexecutor or Forkjoinpool?

First, using Forkjoinpool can use a limited number of threads to accomplish very many tasks that have a parent-child relationship, such as using 4 threads to accomplish more than 2 million tasks. However, when using threadpoolexecutor, it is not possible to do so because thread in threadpoolexecutor cannot choose to take precedence over subtasks, and when it needs to complete 2 million tasks with a parent-child relationship, it also requires 2 million threads. Obviously, this is not feasible.

Ps:forkjoinpool during execution, a large number of subtasks are created, resulting in GC garbage collection, which is important to note.

Java Multi-thread Forkjoinpool

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.