ForkJoin详解

ForkJoin详解

ForkJoin fork分支 jion合并

主要思想:把大任务拆分成小任务,最后把小任务的结果合并

工作窃取:ForkJoin维护的都是双端队列,先执行完的线程会去获取未执行完线程的最后的任务来执行,可以提高效率,但是也可能会引入问题

Long 和long性能相差好大,但是LongStream是真的快

package com.example.juc;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

public class TestForkJoin {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestForkJoin testForkJoin = new TestForkJoin();
        testForkJoin.test0(); //2983ms
        testForkJoin.test0_1(); //241ms
        testForkJoin.test1(); //2440ms
        testForkJoin.test1_1(); //472ms
        testForkJoin.test2(); //110ms 高级程序员


    }

    public void test0() {
        long s = System.currentTimeMillis();
        Long sum = 0L;
        for (long i = 0; i <= 10_0000_0000; i++) {
            sum += i;
        }
        long e = System.currentTimeMillis();
        System.out.println(e - s + "ms, result = " + sum);
    }

    public void test0_1() {
        long s = System.currentTimeMillis();
        long sum = 0L;
        for (long i = 0; i <= 10_0000_0000; i++) {
            sum += i;
        }
        long e = System.currentTimeMillis();
        System.out.println(e - s + "ms, result = " + sum);
    }

    public void test1() throws ExecutionException, InterruptedException {
        long s = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinDemo forkJoinDemo = new ForkJoinDemo(0L, 10_0000_0000L);
        ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinDemo);
        Long sum = submit.get();
        long e = System.currentTimeMillis();
        System.out.println(e - s + "ms, result = " + sum);
    }

    public void test1_1() throws ExecutionException, InterruptedException {
        long s = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinDemo1 forkJoinDemo = new ForkJoinDemo1(0L, 10_0000_0000L);
        ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinDemo);
        Long sum = submit.get();
        long e = System.currentTimeMillis();
        System.out.println(e - s + "ms, result = " + sum);
    }

    public void test2() {
        long s = System.currentTimeMillis();
        Long sum = LongStream.rangeClosed(0, 10_0000_0000L).parallel().reduce(0, Long::sum);
        long e = System.currentTimeMillis();
        System.out.println(e - s + "ms, result = " + sum);
    }

}

class ForkJoinDemo extends RecursiveTask<Long> {
    private static final long serialVersionUID = 8313061473512606355L;

    public ForkJoinDemo(Long start, Long end) {
        this.start = start;
        this.end = end;
    }

    private long start;
    private long end;

    private long temp = 100000L;
    private Long sum = 0L;

    @Override
    protected Long compute() {
        if ((start - end) < temp) {
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            Long middle = start + (end - start) / 2;
            ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
            ForkJoinDemo task2 = new ForkJoinDemo(middle + 1, end);
            task1.fork();
            task2.fork();
            return task1.join() + task2.join();
        }
    }
}

class ForkJoinDemo1 extends RecursiveTask<Long> {
    private static final long serialVersionUID = 8313061473512606355L;

    public ForkJoinDemo1(Long start, Long end) {
        this.start = start;
        this.end = end;
    }

    private long start;
    private long end;

    private long temp = 100000L;
    private long sum = 0L;

    @Override
    protected Long compute() {
        if ((start - end) < temp) {
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            Long middle = start + (end - start) / 2;
            ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
            ForkJoinDemo task2 = new ForkJoinDemo(middle + 1, end);
            task1.fork();
            task2.fork();
            return task1.join() + task2.join();
        }
    }
}


posted @ 2021-12-09 21:41  Oh,mydream!  阅读(77)  评论(0编辑  收藏  举报