java fork/join框架编辑,高效实现任务的拆分与结果的合并

fork/join框架介绍

在jdk中,给我们提供了一种类似于MapReduce的编程模型。用于把一个大的任务拆分成多个小任务单元,分配到多个线程去并发执行,再把各最小单元的返回的结果聚合返回。这样一来,对于大任务的执行效率就大大提升了。下面我以一个简单的例子来介绍一下api的使用。

实例展示

业务需求:把从1到100个数依次相加,返回最终的结果。
业务分析:把100个数拆分成10组,每组10个元素来执行计算。使用RecursiveTask类来实现。
代码展示:

/**
 * 多线程并发求和
 *
 * @author cobee
 * @since 2020-02-28
 */
public class SumJob extends RecursiveTask<Integer> {
     
	// 存放元素的list集合
    private List<Integer> elems;
    private int start;
    private int end;

    public SumJob(List<Integer> elems, int start, int end) {
     
        this.elems = elems;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
     
        int interval = end - start;
        // 以10个为一组计算,执行任务,最小执行单元
        if(interval <= 10){
     
            int sum = 0;
            for(int i = start; i < end; i++){
     
                sum += elems.get(i);
            }
            return sum;
        }else{
     
            // 继续拆分,直到拆分到最小的执行单元
            int x = (end + start) / 2;
            SumJob job1 = new SumJob(elems, start, x);
            job1.fork(); // 任务拆分
            SumJob job2 = new SumJob(elems, x, end);
            job2.fork(); // 任务拆分
            // 合并结果
            Integer join1 = job1.join();
            Integer join2 = job2.join();
            return join1 + join2;
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
     
        List<Integer> elems = new ArrayList<>();
        int sum = 0;
        for(int i = 1; i <= 100; i++){
     
            elems.add(i);
            sum += i;
        }
        System.out.println("for sum:" + sum);
        SumJob job = new SumJob(elems, 0, elems.size());
        ForkJoinPool forkJoinPool = new ForkJoinPool(5, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
        ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(job);
        System.out.println("forkJoin sum:" + forkJoinTask.get());
    }

}

总结

java的fork/join框架使用简单。关键有三个点:第一,如何根据业务来定义你的任务;第二,如何拆分任务;第三,如何合并子任务的结果。

你可能感兴趣的:(java_base,java,forkjoin,fork/join,mapreduce)