美文网首页
ForkJoin实现分而治之

ForkJoin实现分而治之

作者: 刘彦青 | 来源:发表于2019-09-25 11:07 被阅读0次
    • 对于简单的并行任务可以通过"线程池+Future"方案来解决。
    • 如果任务额之间有聚合关系(AND聚合或者OR聚合)用CompletableFuture解决。
    • 批量的并行任务用CompletionService解决。

    并发编程可以分为三个层面的问题: 分工,协作,互斥。

    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的关系。

    ForkJoinPool有窃取队列的性质,空闲队列会窃取忙队列的任务

    建议用不同的ForkJoinPool执行不同类型的计算任务


    **** 码字不易如果对你有帮助请给个关注****

    **** 爱技术爱生活 QQ群: 894109590****

    相关文章

      网友评论

          本文标题:ForkJoin实现分而治之

          本文链接:https://www.haomeiwen.com/subject/ifviuctx.html