学习lambda03-lambda和forkjoin


import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.LongStream;

/**
 继 承 Recur-
 siveTask 来
 创 建 可 以 用
 于分支/合并
 框架的任务
 **/
public class ForkJoinSumCalculator extends RecursiveTask<Long>
{

    /**
     * 不再将任务分
     * 解为子任务的
     * 数组大小 (也就是用于递归出来的条件,当小于10000的时候就会计算(单个子任务)求和结果)
     */
    public static final long THRESHOLD = 3;
    public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();

    private final long[] numbers; //需要求和的数组
    private final int start; //开始
    private final int end;//结束

    /**
     * 公共构造
     * 函数用于
     * 创建主任
     * 务
     * @param numbers
     */
    public ForkJoinSumCalculator(long[] numbers) {
        this(numbers, 0, numbers.length);
    }

    /**
     * 私有构造函数用于以递
     * 归方式为主任务创建子
     * 任务
     * @param numbers
     * @param start
     * @param end
     */
    private ForkJoinSumCalculator(long[] numbers, int start, int end) {
        this.numbers = numbers;
        this.start = start;
        this.end = end;
    }

    private static AtomicInteger integer = new AtomicInteger(0);

    @Override
    protected Long compute() {
        integer.getAndAdd(1);
        int length = end - start;
        if (length <= THRESHOLD) {
            return computeSequentially();
        }
        /**
         * 创建一个子任
         * 务来为数组的
         * 前一半求和
         * 假设numbers = 10 , 那么 new ForkJoinSumCalculator(10, 0,5);
         */
        ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length/2);
        /**
         * 利 用 另 一 个
         * ForkJoinPool
         * 线程异步执行新
         * 创建的子任务
         * 假设numbers = 10 , 那么 new ForkJoinSumCalculator(10, 5,10);
         */
        leftTask.fork();
        ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length/2, end);

        /**
         * 同步(注意是同步,也就是会有阻塞)执行第二个子
         * 任务,有可能允许进
         * 一步递归划分
         */
        Long rightResult = rightTask.compute();
        /**
         * 读取第一个子任务的结果,
         * 如果尚未完成就等待
         */
        Long leftResult = leftTask.join();
        /**
         * 对两个子任务的结果求和
         */
        return leftResult + rightResult;
    }

    private long computeSequentially() {
        long sum = 0;
        for (int i = start; i < end; i++) {
            sum += numbers[i];
        }
        return sum;
    }

    public static long forkJoinSum(long n) {
        long[] numbers = LongStream.rangeClosed(1, n).toArray();
        ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
        return FORK_JOIN_POOL.invoke(task);
    }

    public static void main(String[] args) {
        long l = forkJoinSum(10);
        System.out.println(integer); //打印计数器为7 ,通过断点查看确实是进入了7次
        System.out.println(l);
    }
}

程序执行大概流程
学习lambda03-lambda和forkjoin_第1张图片

你可能感兴趣的:(lambda)