Java7职务并行执行神器,Join框架分析

2019-10-09 01:31 来源:未知

Fork/Join框架是Java7提供的并行施行职责框架,思想是将大任务分解成小任务,然后小职分又可以连续解释,然后每种小职务分别总结出结果再统一齐来,最后将汇总的结果作为大职务结果。其思维和MapReduce的思维非常临近。对于任务的划分,必要各类子职务之间交互独立,能够彼此独立地推行职责,相互之间不影响。

Fork/Join是什么?

Fork/Join框架是Java7提供的并行施行职务框架,思想是将大职分分解成小职务,然后小职分又有啥不可持续解释,然后每一种小任务分别总括出结果再统一同来,最终将聚焦的结果作为大职责结果。其观念和MapReduce的合计非常相近。对于职分的分开,须求各类子职分之间相互独立,能够互为独立地试行职务,相互之间不影响。

Fork/Join的运作流程图如下:

图片 1

image

作者们能够透过Fork/Join单词字面上的情趣去驾驭这一个框架。Fork是叉子分叉的野趣,将在大职责分解成并行的小职责,Join是屡次三番结合的意趣,将要有所并行的小职务的执行结果汇总起来。

图片 2

image

Fork/Join的运作流程图如下:

干活窃取算法

ForkJoin选取了职业窃取(work-stealing)算法,若三个做事线程的天职队列为空未有职责施行时,便从任何干活线程中得到任务积极施行。为了落到实处职业窃取,在干活线程中有限帮忙了双端队列,窃取职分线程从队尾获取职分,被窃取任务线程从队头获取任务。这种机制充裕利用线程进行并行总计,收缩了线程竞争。可是当队列中只存在八个任务了时,多个线程去取反而会招致资源浪费。

行事窃取的运作流程图如下:

[图形上传败北...(image-44d82f-1517087277721)]

图片 3image

Fork/Join核心类

Fork/Join框架首要由子职责、职责调解两局地构成,类等级次序图如下。

图片 4

image

  • ForkJoinPool

ForkJoinPool是ForkJoin框架中的职务调解器,和ThreadPoolExecutor同样达成了谐和的线程池,提供了三种调节子任务的主意:

  1. execute:异步实践钦点职责,无重回结果;

  2. invoke、invokeAll:异步实践内定任务,等待完成才再次回到结果;

  3. submit:异步试行钦定职责,并当即回到贰个Future对象;

  • ForkJoinTask

Fork/Join框架中的实际的实践职分类,有以下两种达成,平常持续那三种完毕类就能够。

  1. RecursiveAction:用于无结果回到的子职责;

  2. RecursiveTask:用于有结果再次来到的子职责;

小编们能够透过Fork/Join单词字面上的意思去了解这一个框架。Fork是叉子分叉的情致,将要大义务分解成并行的小职分,Join是连连结合的情趣,将要有所并行的小职分的实行结果汇总起来。

Fork/Join框架实战

上边实现几个Fork/Join小例子,从1+2+...10亿,每一个义务只好管理1000个数相加,当先一千个的自发性分解成小职责并行管理;并出示了通过不使用Fork/Join和使用时的小时消耗对比。

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinTask extends RecursiveTask<Long> {

    private static final long MAX = 1000000000L;
    private static final long THRESHOLD = 1000L;
    private long start;
    private long end;

    public ForkJoinTask(long start, long end) {
        this.start = start;
        this.end = end;
    }

    public static void main(String[] args) {
        test();
        System.out.println("--------------------");
        testForkJoin();
    }

    private static void test() {
        System.out.println("test");
        long start = System.currentTimeMillis();
        Long sum = 0L;
        for (long i = 0L; i <= MAX; i++) {
            sum += i;
        }
        System.out.println(sum);
        System.out.println(System.currentTimeMillis() - start + "ms");
    }

    private static void testForkJoin() {
        System.out.println("testForkJoin");
        long start = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        Long sum = forkJoinPool.invoke(new ForkJoinTask(1, MAX));
        System.out.println(sum);
        System.out.println(System.currentTimeMillis() - start + "ms");
    }

    @Override
    protected Long compute() {
        long sum = 0;
        if (end - start <= THRESHOLD) {
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            long mid = (start + end) / 2;

            ForkJoinTask task1 = new ForkJoinTask(start, mid);
            task1.fork();

            ForkJoinTask task2 = new ForkJoinTask(mid + 1, end);
            task2.fork();

            return task1.join() + task2.join();
        }
    }

}

那边必要计算结果,所以职务延续的是RecursiveTask类。ForkJoinTask要求贯彻compute方法,在这几个办法里首先须要判别任务是不是低于等于阈值1000,倘若是就一直推行职务。不然分割成多个子职分,每一个子义务在调用fork方法时,又会进来compute方法,看看当前子职责是不是须求持续分割成孙职分,借使无需后续分割,则进行当前子职分并赶回结果。使用join方法会阻塞并等待子任务试行完并获得其结果。

次第输出:

test
500000000500000000
4992ms
--------------------
testForkJoin
500000000500000000
508ms

从结果来看,并行的时刻成本鲜明要有数串行的,那正是并行义务的裨益。

固然如此,在运用Fork/Join时也得小心,不要盲目接纳。

  1. 若是职分拆解的很深,系统内的线程数量聚成堆,导致系统品质品质严重下跌;

  2. 假使函数的调用栈很深,会导致栈内部存款和储蓄器溢出;

图片 5image

ForkJoin选用了事业窃取(work-stealing)算法,若三个做事线程的天职队列为空未有任务推行时,便从别的职业线程中得到任务积极实践。为了落实职业窃取,在干活线程中保险了双端队列,窃取职责线程从队尾获取职分,被窃取任务线程从队头获取职责。这种体制丰富利用线程实行并行总计,收缩了线程竞争。可是当队列中只设有贰个义务了时,两个线程去取反而会促成能源浪费。

行事窃取的周转流程图如下:

图片 6image

Fork/Join框架首要由子职分、职务调治两某些构成,类档期的顺序图如下。

图片 7image

  • ForkJoinPool

ForkJoinPool是ForkJoin框架中的职分调节器,和ThreadPoolExecutor同样达成了和煦的线程池,提供了三种调解子职责的措施:

  1. execute:异步实施内定义务,无再次回到结果;
  2. invoke、invokeAll:异步推行钦定职务,等待完毕才回去结果;
  3. submit:异步实行钦定职务,并立刻回去一个Future对象;
  • ForkJoinTask

Fork/Join框架中的实际的试行任务类,有以下二种实现,日常持续那二种实现类就可以。

  1. RecursiveAction:用于无结果回到的子职分;
  2. RecursiveTask:用于有结果重回的子职责;

上边实现三个Fork/Join小例子,从1+2+...10亿,种种职责只好处理一千个数相加,超越一千个的电动分解成小任务并行处理;并显示了经过不应用Fork/Join和选拔时的时日消耗比较。

import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTask;public class ForkJoinTask extends RecursiveTask<Long> { private static final long MAX = 1000000000L; private static final long THRESHOLD = 1000L; private long start; private long end; public ForkJoinTask(long start, long end) { this.start = start; this.end = end; } public static void main(String[] args) { test(); System.out.println("--------------------"); testForkJoin(); } private static void test() { System.out.println; long start = System.currentTimeMillis(); Long sum = 0L; for (long i = 0L; i <= MAX; i++) { sum += i; } System.out.println; System.out.println(System.currentTimeMillis() - start + "ms"); } private static void testForkJoin() { System.out.println("testForkJoin"); long start = System.currentTimeMillis(); ForkJoinPool forkJoinPool = new ForkJoinPool(); Long sum = forkJoinPool.invoke(new ForkJoinTask; System.out.println; System.out.println(System.currentTimeMillis() - start + "ms"); } @Override protected Long compute() { long sum = 0; if (end - start <= THRESHOLD) { for (long i = start; i <= end; i++) { sum += i; } return sum; } else { long mid = (start + end) / 2; ForkJoinTask task1 = new ForkJoinTask(start, mid); task1.fork(); ForkJoinTask task2 = new ForkJoinTask(mid + 1, end); task2.fork(); return task1.join() + task2.join(); } }}

此地必要总括结果,所以职责延续的是RecursiveTask类。ForkJoinTask须求实现compute方法,在那一个措施里第一必要决断职责是或不是低于等于阈值一千,假设是就径直施行义务。不然分割成三个子职务,种种子职务在调用fork方法时,又会进来compute方法,看看当前子职务是不是要求持续分割成孙职务,要是无需后续分割,则实践当前子任务并回到结果。使用join方法会阻塞并等待子职务奉行完并获得其结果。

程序输出:

test5000000005000000004992ms--------------------testForkJoin500000000500000000508ms

从结果看出,并行的时光费用明显要少于串行的,那正是并行任务的补益。

就算如此,在选择Fork/Join时也得注意,不要盲目选择。

  1. 如果职责拆解的很深,系统内的线程数量聚积,导致系统质量质量严重下滑;
  2. 一旦函数的调用栈很深,会导致栈内存溢出;

越来越多干货推荐

1.史上最强 Java 中高档面试题整理

2.史上最强 Spring Boot & Cloud 教程整理

3.史上最强架构划设想计分布式技能干货整理

越多请扫描下方的二维码关心大家的微信徒人号,干货天天推送!

图片 8Java技术栈

TAG标签:
版权声明:本文由金沙澳门唯一官网发布于编程教学,转载请注明出处:Java7职务并行执行神器,Join框架分析