一、概念:Fork/Join框架是一個把大任務分割成若干個小人物,最終彙總每一個小任務結果後獲得大任務結果的框架。java
二、Fork/Join 框架的設計:框架
步驟1:分隔任務。ide
步驟2:執行任務合併結果。this
Fork/Join 使用兩個類來完成以上兩件事情。spa
1.ForkJoinTask:我要使用ForkJoin框架,必須首先建立一個ForkJoin任務,它提供在任務中執行fork()和join()操做的機制,一般狀況下,咱們不須要直接繼承ForkJoinTask類,只須要繼承它的子類。線程
RecursiveAction :用於沒有返回結果的任務。設計
RecursiveTask: 用於有返回結果的任務。code
2.ForkJoinPool:ForkJoinTask須要經過ForkJoinPool來執行。orm
三、使用Fork/Join框架:blog
需求是:計算1+2+3+4的結果.
使用Fork/Join框架首先要考慮到的是如何分割任務,若是但願每一個子任務最多執行兩個數的相加,那麼咱們設置分割的閾值是2,因爲是4個數字相加,因此Fork/Join框架會把這個任務Fork成兩個子任務,子任務一負責計算1+2,子任務二負責3+4,而後再join兩個子任務的結果。由於是有結果的任務,因此必須繼承RecursiveTask。
package com.test; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; public class CountTask extends RecursiveTask<Integer> { private static final int THRESHOLD = 2; // 閾值 private int start; private int end; public CountTask(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; } } else { // 若是任務大於閾值,就分裂成兩個子任務計算 int middle = (start + end) / 2; CountTask leftTask = new CountTask(start, middle); CountTask rightTask = new CountTask(middle + 1, end); // 執行子任務 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(); // 生成一個計算任務,負責計算1+2+3+4 CountTask task = new CountTask(1, 4); // 執行一個任務 Future<Integer> result = forkJoinPool.submit(task); try { System.out.println(result.get()); } catch (Exception e) { e.printStackTrace(); } } }
四、Fork/join框架的異常處理:
ForkJoinTask在執行的時候可能會拋出異常,可是咱們沒辦法在主線程裏直接捕獲異常,因此ForkJoinTask提供了isCompletedAbnormally()方法來檢查任務是否已經跑出異常或被取消了,而且能夠經過ForkJoinTask的getExceptiohn方法獲取異常:
if (task.isCompletedAbnormally()) { System.out.println(task.getException()); }