• 13. ForkJoin


    ForkJoin :: 分支合并 (JDK 1.7)

    • 并行执行任务,提高效率。

    • 使用场景:大数据量

    • 将大任务拆成小任务

    ForkJoin 特点:工作窃取

    这个里面维护的都是双端队列,如果一方执行完了,获取另外一方的未完成的任务进行执行

    ForkJoin 的操作

    package pers.vincent.matrix.subject.forkjoin;
    
    import java.util.concurrent.ForkJoinTask;
    import java.util.concurrent.RecursiveTask;
    
    public class ForkJoinDemp extends RecursiveTask<Long> {
    
        private Long start;
    
        private Long end;
    
        private Long temp = 10_0000L;
    
        public ForkJoinDemp(Long start, Long end){
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected Long compute() {
            if((end-start) <= temp){
                Long result = 0L;
                for (Long i = start; i <= end; i++) {
                    result += i;
                }
                return result;
            }else{
                Long middle = (end + start) / 2;
    
                ForkJoinDemp task1 = new ForkJoinDemp(start, middle);
                task1.fork();
                ForkJoinDemp task2 = new ForkJoinDemp(middle+1, end);
                task2.fork();
    
                return task1.join() + task2.join();
            }
        }
    }
    
    

    测试代码:(普通 - ForkJoin - Stream 流计算)

    package pers.vincent.matrix.subject.forkjoin;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ForkJoinPool;
    import java.util.concurrent.ForkJoinTask;
    import java.util.stream.LongStream;
    
    public class Test1 {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            long start = 0L;
            long end = 10_0000_0000L;
            test3(start, end);
        }
    
        /**
         * TOTAL TIME = 5699
         * @param start
         * @param end
         */
        public static void test1(Long start, Long end){
            long beginTime = System.currentTimeMillis();
    
            Long result = start;
            for (Long i = 0L; i <=end; i++) {
                result += i;
            }
    
            long endTime = System.currentTimeMillis();
    
            System.out.println("Time===" + (endTime-beginTime) + ", result = " + result);
        }
    
        /**
         * TOTAL TIME : 4908
         * @param start
         * @param end
         * @throws ExecutionException
         * @throws InterruptedException
         */
        public static void test2(Long start, Long end) throws ExecutionException, InterruptedException {
            long beginTime = System.currentTimeMillis();
    
            ForkJoinPool forkJoinPool = new ForkJoinPool();
            ForkJoinTask<Long> forkJoinDemp = new ForkJoinDemp(start, end);
            ForkJoinTask<Long> sum = forkJoinPool.submit(forkJoinDemp);
    
            long result = sum.get();
    
            long endTime = System.currentTimeMillis();
    
            System.out.println("Time===" + (endTime-beginTime) + result);
        }
    
        /**
         * TOTAL TIME = 250
         * @param start
         * @param end
         */
        public static void test3(Long start, Long end){
            long beginTime = System.currentTimeMillis();
    
            long sum = LongStream.rangeClosed(start, end).parallel().reduce(0, Long::sum);
    
            long endTime = System.currentTimeMillis();
    
            System.out.println("Time===" + (endTime-beginTime) + ", result = " + sum);
        }
    }
    
  • 相关阅读:
    var、let、const
    面向女朋友自我介绍
    ES6——class
    一个错误引发的——对异步回调与for循环(小白错误,大神勿进)
    关于this
    关于作用域
    HTML5 8
    HTML5 7
    HTML5 6
    HTML5 4
  • 原文地址:https://www.cnblogs.com/blackBlog/p/13451530.html
Copyright © 2020-2023  润新知