Java Fork/join Framework

Source: Internet
Author: User

Problems encountered in application parallel computing

When the hardware processing ability cannot massage the law perpendicular development, chooses the horizontal development. Multicore processors have been widely used, and the core number of future processors will be further released, even hundreds of thousands. Many applications now run on multi-core processors and do not get a good performance boost because the concurrency of the application is not strong enough to utilize the computing resources reasonably and efficiently. A linear calculation can only be supported by the calculation of one of the N points.

To improve the efficiency of application execution on multicore processors, you can only find ways to improve the parallelism of the application itself. The general practice is to use multi-threading, to allow more tasks to be processed at the same time, or to let some operations execute asynchronously, this simple multithreading method can effectively utilize processing resources when the processor core number is relatively small, because in the case of less processor cores, a few more tasks can be executed in parallel. But when the number of processor cores is large, hundreds of thousands of times, this task-based concurrency approach also does not take full advantage of processing resources because the general application does not have so many concurrent processing tasks (the server program is an exception). Therefore, you can only consider splitting a task into multiple units, each of which performs the final merging of the results of each cell. A parallel split of a task, one way is to hope for a hardware platform or operating system, but there is no good result in this field. Another option is to rely on the application itself to execute the task through the line-wrap.

Fork/join Frame

Depending on the application itself, the complexity of using a simple multithreaded program is bound to be large. This requires a better paradigm or tool to handle this kind of problem on behalf of the programmer. Java 7 was also aware of the problem, and the Fork/join Parallel computing framework developed by Doug Lea was integrated into the standard library. By using the Fork/join model, software developers can easily take advantage of the computing power of multi-core platforms. Although not fully transparent to software developers, the Fork/join model has greatly simplified the trivial work of writing concurrent programs. For applications that conform to Fork/join mode, software developers no longer have to deal with a variety of parallel related transactions, such as synchronization, communication, and so on, known for difficult to debug, such as deadlocks and data race errors will not appear, raising the level of thinking. You can think of the fork/join pattern as a parallel version of the Divide and conquer strategy, focusing only on how to divide tasks and combine intermediate results, leaving the rest to the Fork/join framework. However, the Fork/join parallel computing framework is not a silver bullet and does not solve the concurrency problems of all applications on hyper-core processors.

If an application can be decomposed into multiple subtasks, and the result of combining multiple sub-tasks is able to get the final answer, then this application is suitable to be solved with Fork/join mode. The principle is as follows.

What the application developer needs to do is split the task and combine the intermediate results of each subtask without having to worry about threading and locking.

Second, work stealing algorithm

Refers to the execution of a thread stealing a task from another queue. The scenario used is a large task split into smaller tasks, in order to reduce the competition between threads, put these subtasks in separate queues, and each queue has a separate thread to perform the tasks in the queue, and the thread and queue one by one correspond. But there is a situation where a thread finishes its own queue, and a queue of B threads has a lot of tasks to deal with. A is a very enthusiastic thread, want to help in the past, but if two threads access the same queue, there will be competition, so a think of a way, from the tail of the double-ended queue to carry out the task. The b thread is always executed from the head of the double-ended queue (the task is a separate small task), so that the A-thread feels like a thief stealing a B-thread.

Advantages of the work-stealing algorithm:

The thread is used for parallel computing, which reduces the competition between threads.

Disadvantages of the work-stealing algorithm:

1. If there is only one task in the double-ended queue, there will be competition between the threads.

2. The stealing algorithm consumes more system resources, such as creating multiple threads and multiple double-ended queues.

Third, the framework design

Two important classes in the Fork/join:

1. Forkjointask: Using this framework, you need to create a Forkjoin task that provides a mechanism for performing fork and join operations in a task. In general, we do not need to directly inherit the Forkjointask class, only to inherit its subclass, its subclass has two:

A, recursiveaction: for tasks that do not return results.

B, Recursivetask: Used for tasks that have returned results.

2, Forkjoinpool: The task forkjointask need to be executed through Forkjoinpool.

 1 package test; 2 3 Import java.util.concurrent.ExecutionException; 4 Import Java.util.concurrent.ForkJoinPool; 5 Import Java.util.concurrent.Future; 6 Import Java.util.concurrent.RecursiveTask;  7 8 9 public class Counttask extends recursivetask<integer>10 {One private static final long Serialversionuid =     1L;12//Threshold of private static final int THRESHOLD = 2;14 private int start;15 private int end;16 17 Public counttask (int start, int end) {This.start = start;20 this.end = end;21}22 @Ov  ERRIDE24 protected Integer Compute () {int sum = 0;27//Determine if the task is small enough to Boolean Cancompute = (End-start) <= threshold;29 if (Cancompute) 30 {31//If it is less than the threshold value, the operation is I=start; i<=end; i++) {$ + + i;35}36}37 else38 {39//IF is greater than the threshold value, the task is then split by the middle = (start + End)/2;41 counttask lefttask = new Counttask (start,middle); Counttask righttask = new Counttask (middle+1,end); 43//Perform subtasks lefttask.fork (); Righttask.fork (); 46//Waiting for subtasks             Execute and get execution result Leftresult int = Lefttask.join (); Rightresult int = Righttask.join (); 49     Merge subtask sum = Leftresult + rightresult;51}53 return sum;54}55 56 public static void Main (string[] args) Cou {forkjoinpool Forkjoinpool = new Forkjoinpool ();          Nttask task = new Counttask (1,6); 60//Perform a task future<integer> result = Forkjoinpool.submit (Task); 62  try63 {System.out.println (Result.get ());}66 catch (interruptedexception             e) e.printstacktrace ();}70 catch (Executionexception e) 71 {72 E.printstacktrace (); 73}74 75}76 77} 

This program is to split the 1+2+3+4+5+6 into 1+2;3+4;5+6 three parts of the sub-program after the calculation of the merger.

A simple example

Let's start by looking at a simple fork/join task definition.

Java code
  1. Public class Calculator extends recursivetask<integer> {
  2. private static final int THRESHOLD = 100;
  3. private int start;
  4. private int end;
  5. Public Calculator (int start, int end) {
  6. This.start = start;
  7. this.end = end;
  8. }
  9. @Override
  10. protected Integer Compute () {
  11. int sum = 0;
  12. if ((Start-end) < THRESHOLD) {
  13. For (int i = start; i< end;i++) {
  14. sum + = i;
  15. }
  16. }else{
  17. int middle = (start + end)/2;
  18. Calculator left = new Calculator (Start, middle);
  19. Calculator right = new Calculator (middle + 1, end);
  20. Left.fork ();
  21. Right.fork ();
  22. sum = Left.join () + Right.join ();
  23. }
  24. return sum;
  25. }
  26. }

In this code, a cumulative task is defined, in the compute method, to determine whether the current calculation range is less than a value, if it is calculated, if not, split the task into a sub-task, and merge the intermediate results of the subtasks. The program recursively completes the task splitting and calculation.

After the task is defined, the task is performed, and Fork/join provides an extension thread pool for the executor framework to perform the task.

Java code
    1. @Test
    2. Public Void Run () throws exception{
    3. Forkjoinpool Forkjoinpool = new Forkjoinpool ();
    4. future<integer> result = Forkjoinpool.submit (new Calculator (0, 10000));
    5. Assertequals (new Integer (49995000), Result.get ());
    6. }
Main classes of the Fork/join framework


Recursiveaction to continue for tasks that do not require a return value.

The Recursivetask evaluates the return value type by setting the generic parameter.

Forkjoinpool provides a series of submit methods to calculate tasks. Forkjoinpool the default number of threads is obtained through runtime.availableprocessors (), because in computationally intensive tasks, threads that get more than the number of processing cores do not get more performance gains.

Public <T> forkjointask<t> Submit (forkjointask<t> Task) {
Dosubmit (Task);
return task;
}

The Sumit method returns the task itself, and Forkjointask implements the future interface, so it can wait for the result to be obtained.

Another example

This example sorts the array in parallel, does not need to return the result, so inherits the Recursiveaction.

Java code
  1. Public class Sorttask extends Recursiveaction {
  2. final long[] array;
  3. final int start;
  4. final int end;
  5. private int THRESHOLD = 100; //for demo only
  6. Public Sorttask (long[] array) {
  7. This.array = array;
  8. This.start = 0;
  9. this.end = array.length- 1;
  10. }
  11. Public Sorttask (long[] array, int start, int end) {
  12. This.array = array;
  13. This.start = start;
  14. this.end = end;
  15. }
  16. protected void Compute () {
  17. if (End-start < THRESHOLD)
  18. Sequentiallysort (array, start, end);
  19. else {
  20. int pivot = partition (array, start, end);
  21. new Sorttask (array, start, Pivot- 1). Fork ();
  22. new Sorttask (array, pivot + 1, end). Fork ();
  23. }
  24. }
  25. private int partition (long[] array, int start, int end) {
  26. long x = Array[end];
  27. int i = start- 1;
  28. For (int j = start; J < End; J + +) {
  29. if (Array[j] <= x) {
  30. i++;
  31. Swap (array, I, j);
  32. }
  33. }
  34. Swap (array, i + 1, end);
  35. return i + 1;
  36. }
  37. private void swap (long[] array, int i, int j) {
  38. if (i! = j) {
  39. Long temp = array[i];
  40. Array[i] = Array[j];
  41. ARRAY[J] = temp;
  42. }
  43. }
  44. private void Sequentiallysort (long[] array, int lo, int hi) {
  45. Arrays.sort (Array, lo, hi + 1);
  46. }
  47. }
Java code
  1. @Test
  2. Public Void Run () throws interruptedexception {
  3. Forkjoinpool Forkjoinpool = new Forkjoinpool ();
  4. Random rnd = new Random ();
  5. long[] array = new long[size];
  6. For (int i = 0; i < SIZE; i++) {
  7. Array[i] = Rnd.nextint ();
  8. }
  9. Forkjoinpool.submit (new Sorttask (array));
  10. Forkjoinpool.shutdown ();
  11. Forkjoinpool.awaittermination (timeunit.seconds);
  12. For (int i = 1; i < SIZE; i++) {
  13. Asserttrue (Array[i- 1] < array[i]);
  14. }
  15. }
Hands-on Try

The code for the Fork/join framework has been integrated into the latest JDK7 binary Snapshot releases, which can be downloaded from this address.

The code in this article is shown in the attachment.

    • Fork-join.zip (27.2 KB)
    • Download number of times: 697

Java Fork/join Framework

Related Article

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.