ForkJoin详解

HeJin大约 1 分钟JavaJUC并发编程

什么是ForkJoin

ForkJoin在JDK1.7出来。并行执行任务,提高效率。大数据量。

大数据:MapReduce(把大任务拆分成小任务)。

ForkJoin特点:工作窃取。这个里面维护的都是双端队列。

image-20210312193919124
image-20210312193919124

ForkJoin使用

1、ForkJoinPool 来执行

image-20210312195058395
image-20210312195058395

2、计算任务 execute(ForkJoinTask<?> task)

image-20210312195429017
image-20210312195429017

RecursiveTask

image-20210312195550803
image-20210312195550803

3、计算类继承RecursiveTask

代码

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test1();
        test2();
        test3();
    }

    /**
     * 普通程序员
     */
    public static void test1(){
        Long start = System.currentTimeMillis();

        Long sum = 0L;
        for (Long i = 1L; i <= 10_0000_0000L; i++) {
            sum += i;
        }

        Long end = System.currentTimeMillis();
        System.out.println("普通的程序员:sum = " + sum + " 时间:" + (end - start));
    }

    /**
     * 使用ForkJoin
     */
    public static void test2() throws ExecutionException, InterruptedException {
        Long start = System.currentTimeMillis();

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinDemo(0L,10_0000_0000L);
        // 提交任务
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);
        Long sum = submit.get();

        Long end = System.currentTimeMillis();
        System.out.println("使用ForkJoin:sum = " + sum + " 时间:" + (end - start));
    }

    /**
     * 更牛逼的程序员
     */
    public static void test3(){
        Long start = System.currentTimeMillis();

        // Stream并行流
        long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);

        Long end = System.currentTimeMillis();
        System.out.println("更牛逼的程序员:sum = " +sum+ " 时间:" + (end - start));
    }
}

结果:

普通的程序员:sum = 500000000500000000 时间:5375
使用ForkJoin:sum = 499934463999828390 时间:3548
更牛逼的程序员:sum = 500000000500000000 时间:144

Process finished with exit code 0