java fork/join框架

一、概念: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());
        }
相關文章
相關標籤/搜索