java8之ForkJoin框架的使用

lyzx_in_csdn發表於2018-08-11
forkjoin框架
標題

forkjoin框架最基本的介紹

package com.lyzx.concurrent.threadPool;

import java.util.concurrent.*;

/**
 * 分支合併執行緒池(mapReduce 類似的設計思想)。適合用於處理複雜任務。
 * 初始化執行緒容量與 CPU 核心數相關。
 * 執行緒池中執行的內容必須是 ForkJoinTask 的子型別(RecursiveTask,RecursiveAction)。
 * ForkJoinPool - 分支合併執行緒池。 可以遞迴完成複雜任務。 要求可分支合併的任務必須
 * 是 ForkJoinTask 型別的子型別。 其中提供了分支和合並的能力。 ForkJoinTask 型別提供了兩個
 * 抽象子型別, RecursiveTask 有返回結果的分支合併任務,RecursiveAction 無返回結果的分支合併任務。(
 * Callable/Runnable) compute 方法:就是任務的執行邏輯。
 * ForkJoinPool 沒有所謂的容量。預設都是 1 個執行緒。根據任務自動的分支新的子執行緒。
 * 當子執行緒任務結束後,自動合併。 所謂自動是根據 fork 和 join 兩個方法實現的。
 * 應用: 主要是做科學計算或天文計算的。 資料分析的。
 */
public class ForkJoinPoolTest{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long[] arr = new long[20000];
        for(int i=0;i<arr.length;i++){
            arr[i]=i;
        }

        ForkJoinPool pool = new ForkJoinPool();
        JoinTask task = new JoinTask(arr,0,arr.length,50);
        Future<Long> future = pool.submit(task);
        System.out.println(future.get());
    }
}

class JoinTask extends RecursiveTask<Long>{
    private int start,end;
    private long[] arr;
    private int target;

    public JoinTask(long[] arr,int start,int end,int target){
        this.arr = arr;
        this.start = start;
        this.end = end;
        this.target = target;
    }

    @Override
    protected Long compute() {
        /**
         * 如果分配的陣列大小達到了指定的大小就執行相加的操作
         * 否則就繼續拆分
         */
        if(end - start <= target){
            Long result = 0L;
            for(int i=start;i<end;i++){
                result+= arr[i];
            }
            return result;
        }else{
            int mid = start + (end - start)/2;
            JoinTask j1 = new JoinTask(arr,start,mid,target);
            JoinTask j2 = new JoinTask(arr,mid,end,target);
            //fork()方法時繼續查分即會繼續呼叫compute方法
            j1.fork();
            j2.fork();
            return j1.join()+j2.join();
        }
    }
}

 

相關文章