JAVA并发编程Fork/Join(分而治之思想)之(ForkJoinPool/ForkJoinTask)

Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果从而得到这个大任务的结果。

这里我们也借助这种思想来处理一个超大任务的运算,采用ForkJoinPool/ForkJoinTask这种方式。

我们来看一段ForkJoinPool/ForkJoinTask方式实现的代码

package com.forkjoin;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * ForkJoinPool
 * 解决方案采用多线程拆分任务实现(Fork/join)
 *
 * @author 小辉GE/小辉哥
 * <p>
 * 2019年8月10日 下午19:30:00
 */
public class ParallelForkJoinPool {
    public static void main(String[] args) throws IOException {
        // 定义arry数组
        int[] arry = new int[10000];
        for (int i = 0; i < arry.length; i++) {
            arry[i] = (int) (Math.random() * 1000);
        }
        // 直接执行方式
        System.out.println("直接执行运算结果是:" + Arrays.stream(arry).sum());

        // Fork/join方式(ForkJoinPool产生的是精灵线程/daemon)
        ForkJoinPool fjp = new ForkJoinPool();
        AddTask task = new AddTask(0, arry.length, arry);
        fjp.execute(task);
        Long result = task.join();
        System.out.println("Fork/join执行运算结果是:" + result);
    }

    // RecursiveTask 实现方式有返回值
    // RecursiveAction 实现方式无返回值
    static class AddTask extends RecursiveTask<Long> {
        int start;
        int end;
        int middle = 500;
        int[] arry;

        AddTask(int start_, int end_, int[] arry_) {
            start = start_;
            end = end_;
            arry = arry_;
        }

        @Override
        protected Long compute() {
            if (end - start <= middle) {
                return getSum(start, end, arry);
            }
            int index = start + (end - start) / 2;
            AddTask subTask1 = new AddTask(start, index, arry);
            AddTask subTask2 = new AddTask(index, end, arry);
            subTask1.fork();
            subTask2.fork();
            return subTask1.join() + subTask2.join();
        }
    }

    /**
     * 实现begin到end求和
     *
     * @param begin
     * @param end
     * @param arry
     * @return
     */
    static Long getSum(int begin, int end, int[] arry) {
        Long sum = 0l;
        for (int i = begin; i < end; i++)
            sum += arry[i];
        return sum;
    }
}


测试输出结果如下:

结果分析:

其实我们可以看出,两种方式运算结果都是一致的。如果我们把运算时间打出来,也可以看出ForkJoinPool/ForkJoinTask方式执行效率也会高很多。

以上代码仅供参考,如有不当之处,欢迎指出!!!

更多干货,欢迎大家关注和联系我。期待和大家一起更好的交流、探讨技术!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章