ForkJoin實現分而治之

  • 對於簡單的並行任務能夠經過"線程池+Future"方案來解決。
  • 若是任務額之間有聚合關係(AND聚合或者OR聚合)用CompletableFuture解決。
  • 批量的並行任務用CompletionService解決。

併發編程能夠分爲三個層面的問題: 分工,協做,互斥。java

ForkJoin有什麼用

Fork/Join是一個並行計算的框架,主要就是用來支持分治任務模型的,這個計算框架裏的Fork對應的是分治任務模型裏的任務分解,Join對應的是結果合併。算法

什麼是分治

把一個複雜的問題分解成多個類似的子問題,而後把子問題分解成更小的子問題,知道子問題簡單到能夠直接求解。編程

算法領域有分治算法(歸併排序、快速排序都屬於分治算法,二 分法查找也是一種分治算法);大數MapReduce也是。併發

分治模型

分治任務能夠分紅兩個階段:任務分解,結果合併。框架

Fork/Join的使用

Fork/Join計算框架主要包含兩部分,一部分是分治任務的線程池ForkJoinPool,另外一部分是分治任務ForkJoinTask。這兩部分的關係相似ThreadPoolExecutor和 Runnable的關係,均可以理解爲提交任務到線程池,只不過度治任務有本身獨特類型ForkJoinTask。異步

ForkJoinTask
  • ForkJoinTask是一個抽象類最核心的是fork()方法和join()方法,fork()會異步地執行一個子任務,join()會阻塞當前線程來等待子任務的執行結果。
  • ForkJoinTask有連個子類:
    • RecursiveAction:用遞歸的方式來處理分治任務,compute()方法沒有返回值。
    • RecursiveTask:用遞歸的方式來處理分治任務,compute()方法有返回值。

使用ForkJoinTask實現計算斐波那契數列

package com.thread;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 實現斐波那契數列
 * 求出第n個斐波那契數列值
 **/
public class ForkJoinDemo {
    public static void main(String[] args) {
        //建立分治任務線程池
        ForkJoinPool fjp = new ForkJoinPool(4);
        //建立分治任務
        Fibonacci fib = new Fibonacci(4);
        //啓動分治任務
        Integer result = fjp.invoke(fib);
        //輸出結果
        System.out.println(result);
    }
    static class Fibonacci extends RecursiveTask<Integer>{
        final int n;
        public Fibonacci(int n){
            this.n = n;
        }
        @Override
        protected Integer compute() {
            if (n <= 1){
                return  n;
            }
            Fibonacci f1 = new Fibonacci(n-1);
            //建立⼦任務
            f1.fork();
            Fibonacci f2 = new Fibonacci(n-2);
            //等待子任務結果,併合並結果.
            return f2.compute() + f1.join();
        }
    }
}

ForkJoinPool與ForkJoinTask關係相似ThreadPoolExecutor和Runnable的關係。ide

ForkJoinPool有竊取隊列的性質,空閒隊列會竊取忙隊列的任務this

建議用不一樣的ForkJoinPool執行不一樣類型的計算任務線程


**** 碼字不易若是對你有幫助請給個關注****3d

**** 愛技術愛生活 QQ羣: 894109590****

相關文章
相關標籤/搜索