ForkJoin框架

ForkJoin框架

package com.zenqgifeng.practicedemo.jdk8newproperties;

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

/**
 * @author zengqifeng
 * @version 1.0
 * @date 2020/1/3 16:12
 * Fork join框架 :任务分治再合并  主要算法:分治算法+任务窃取算法
 * 其中:任务窃取算法是这个框架的核心算法,主要就是充分利用多核CPU的每一个核心
 * 该框架分三部分,我们只需专注任务的fork和join
 *      1、线程成
 *      2、任务
 *      3、执行任务的线程
 *
 *  并行与顺序间的矛盾
 *      任务拆分分给多个线程队列中执行,不能保证之前数据的顺序
 *      思考:rocketmq在使用多线程发送消费消息时,如何保证消息的顺序性机制
 *          有顺序的消息打个标记(这一类打了标记的消息消费具有顺序性),放到同一个队列中
 *
 *  能够使用多线程的前提和注意事项
 *      前提:多线程是基于多核CPU的,如果当前是单核或者CPU负载很大,使用多线程反而提升不了效率
 *      注意事项:多线程的使用虽然能提高效率,但却伴随着线程安全问题,以及无法保证顺序性数据的顺序
 *                  因此都需要提出解决方案。
 */
public class Demo06 {



    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        ForkJoinPool pool = new ForkJoinPool();
        SumRecursiveTask task = new SumRecursiveTask(1L, 100000L);
        Long sum = pool.invoke(task);
        System.out.println(sum);
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }
}

class SumRecursiveTask extends RecursiveTask<Long> {
    //大于3000就fork,否则join
    private static final Long THREESHOLD = 3000L;
    //
    private Long start ;
    private Long end;

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

    public Long getStart() {
        return start;
    }

    public void setStart(Long start) {
        this.start = start;
    }

    public Long getEnd() {
        return end;
    }

    public void setEnd(Long end) {
        this.end = end;
    }

    /**
     * 任务的fork 和 join
     */
    @Override
    protected Long compute() {
        Long length = end - start;
        if (length < THREESHOLD) {
            //效率可看数据值较小时,循环效率高,数据较大时,流效率高,可测试并行流效率怎么样
            //求和 1000000000求和时: 4069
            //求和 100000求和时: 10
            /*Long sum = 0L;
            for (Long i=start; i<=end;i++) {
                sum +=i;
            }*/

            //求和 1000000000求和时: 455
            //求和 100000求和时: 45
            long sum = LongStream.rangeClosed(start, end).sum();
            return sum;
        } else {
            //fork  and  join
            Long middle = (end + start)/2;
            SumRecursiveTask left = new SumRecursiveTask(start, middle);
            left.fork();
            SumRecursiveTask right = new SumRecursiveTask(middle + 1, end);
            right.fork();
            return left.join() + right.join();
        }
    }
}

你可能感兴趣的:(JDK8新特性)