ForkJoin使用

一、Fork Join    
分而治之的辦法

JDk爲Fork/Join框架提供了很好的支持,我們想要用這個算法首先得創建一個Fork/Join任務,在JDK中這個任務就叫做:ForJoinTask,只要繼承這個類就可以創建一個任務類,但是實際使用中並不是直接繼承ForkJoinTask類,而是繼承它的子類,它有兩個子類,分別是RecursiveAction和RecursiveTask,它們之間的區別是是否返回任務結果,前者用於沒有返回結果的任務,後者用於有返回結果的任務。

ForkJoinPool
RecursiveTask
RecursiveAction

 

二、RecursiveTask使用

ForkJoinPoolTest:

 1 package com.cy.java8;
 2 
 3 import java.util.concurrent.ForkJoinPool;
 4 import com.cy.java8.AccumulatorRecursiveAction.AccumulatorHelper;
 5 
 6 public class ForkJoinPoolTest {
 7 
 8     private static int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 9 
10     public static void main(String[] args) {
11         System.out.println("result = " + calc());
12 
13         AccumulatorRecursiveTask task = new AccumulatorRecursiveTask(0, data.length - 1, data);
14         ForkJoinPool forkJoinPool = new ForkJoinPool();
15         Integer result = forkJoinPool.invoke(task);     //同步調用
16         System.out.println("AccumulatorRecursiveTask result = " + result);
17 
18         AccumulatorRecursiveAction action = new AccumulatorRecursiveAction(0, data.length - 1, data);
19         forkJoinPool.invoke(action);
20         System.out.println("AccumulatorRecursiveAction result = " + AccumulatorHelper.getResult());
21         AccumulatorHelper.reset();
22     }
23 
24     /**
25      * 普通方法計算data的和
26      */
27     private static int calc() {
28         int result = 0;
29         for (int i = 0; i < data.length; i++) {
30             result += data[i];
31         }
32         return result;
33     }
34 }

AccumulatorRecursiveTask

 1 package com.cy.java8;
 2 
 3 import java.util.concurrent.RecursiveTask;
 4 
 5 /**
 6  * 繼承RecursiveTask,用於與結果返回的任務
 7  */
 8 public class AccumulatorRecursiveTask extends RecursiveTask<Integer> {
 9 
10     //累加的起始下標值
11     private final int start;
12     private final int end;
13     private final int[] data;
14 
15     //閾值爲3,當小於等於這個值的時候進行計算
16     private final int LIMIT = 3;
17 
18     public AccumulatorRecursiveTask(int start, int end, int[] data) {
19         this.start = start;
20         this.end = end;
21         this.data = data;
22     }
23 
24     @Override
25     protected Integer compute() {
26         if (end - start < LIMIT) {
27             int result = 0;
28             for (int i = start; i <= end; i++) {
29                 result += data[i];
30             }
31             return result;
32         }
33 
34         int mid = (start + end) / 2;
35 
36         //分爲兩個任務
37         AccumulatorRecursiveTask left = new AccumulatorRecursiveTask(start, mid, data);
38         AccumulatorRecursiveTask right = new AccumulatorRecursiveTask(mid + 1, end, data);
39         /*
40         //執行子任務
41         left.fork();
42         right.fork();
43         //等待子任務完成
44         Integer leftResult = left.join();
45         Integer rightResult = right.join();
46         //合併子任務
47         return rightResult + leftResult;
48         */
49 
50         //提交任務
51         invokeAll(left, right);
52         return left.join() + right.join();
53     }
54 }

 

三、RecursiveAction使用  

 1 package com.cy.java8;
 2 
 3 import java.util.concurrent.RecursiveAction;
 4 import java.util.concurrent.atomic.AtomicInteger;
 5 
 6 public class AccumulatorRecursiveAction extends RecursiveAction {
 7     private int start;
 8     private int end;
 9     private int[] data;
10     private final int LIMIT = 3;
11 
12     public AccumulatorRecursiveAction(int start, int end, int[] data) {
13         this.start = start;
14         this.end = end;
15         this.data = data;
16     }
17 
18     @Override
19     protected void compute() {
20         if (end - start < LIMIT) {
21             for (int i = start; i <= end; i++) {
22                 AccumulatorHelper.accumulate(data[i]);
23             }
24         } else {
25             int mid = (start + end) / 2;
26             AccumulatorRecursiveAction left = new AccumulatorRecursiveAction(start, mid, data);
27             AccumulatorRecursiveAction right = new AccumulatorRecursiveAction(mid + 1, end, data);
28             /*left.fork();
29             right.fork();
30             left.join();
31             right.join();*/
32             invokeAll(left, right);
33         }
34     }
35 
36     static class AccumulatorHelper{
37         private static final AtomicInteger result = new AtomicInteger(0);
38 
39         private static void accumulate(int value){
40             result.getAndAdd(value);
41         }
42 
43         public static int getResult(){
44             return result.get();
45         }
46 
47         public static void reset(){
48             result.set(0);
49         }
50     }
51 }

ForkJoinPoolTest的執行結果:

result = 55
AccumulatorRecursiveTask result = 55
AccumulatorRecursiveAction result = 55

 

 注:

1、RecursiveAction 提供的方法 invokeAll()。它表示:啓動所有的任務,並在所有任務都正常結束後返回。如果其中一個任務出現異常,則其它所有的任務都取消。invokeAll() 的參數還可以是任務的數組。

 

 

 

 

 

 

 

-----------

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章