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****

相关文章
相关标签/搜索