Fork/Join框架的简单使用

原文地址:《Fork/Join框架的简单使用》
1、什么是Fork/Join框架
fork操作的作用是把一个大的任务划分成若干个较小的任务。在这个划分过程一般是递归进行的。直到将任务划分到合适的大小为止。需要恰当地选取子问题的大小。太大的子问题不利于通过并行方式来提高性能,而太小的子问题则会带来较大的额外开销。每个子问题计算完成后,可以得到关于整个问题的部分解。join操作的作用是把这些分解任务的结果组织起来,得到完整解。 简单的说,ForkJoin其核心思想就是分治。Fork分解任务,Join收集数据。

2、Fork/Join框架简单使用实例
JDK1.7之后,jdk中添加了相关的Fork/Join代码,主要分为任务实现代码和任务执行代码,每个具体的任务都需要继承RecursiveTask 和RecursiveAction,其中RecursiveTask任务执行后会返回结果,而RecursiveAction不返回结果,这里给出RecursiveTask使用代码

import java.util.concurrent.RecursiveTask;

public class SumTask extends RecursiveTask{

private int start;
private int end;
private long[] datas;

public SumTask(int start,int end,long[] datas){
    this.start = start;
    this.end = end;
    this.datas = datas;
}

@Override
protected Long compute() {
    if(end-start<50000){
        long sum = 0L;
        for(int i = start;i<end;i++){
            sum += datas[i];
        }
        return sum;
    }
    int middle = start+(end-start)/2;
    SumTask leftTask = new SumTask(start,middle,datas);
    SumTask rightTask = new SumTask(middle,end,datas);
    leftTask.fork();
    rightTask.fork();
    return leftTask.join()+rightTask.join();
}

}
这是一个简单的累加任务,通过使用SumTask对300000000个long型数据进行累加,通过与正常的for循环累加速度对比,可以发现使用SumTask的累加速度要优于for循环的累加速度(Fork/Join框架相关变量初始化时间除外)

3、代码测试结果
使用main方法对SumTask进行累加速度测试,测试代码如下:

private static Random random = new Random();

public static void main(String[] args){
    long[] datas = new long[300000000];
    for(int i = 0;i<300000000;i++){
        datas[i] = random.nextLong();
    }
    ForkJoinPool pool = new ForkJoinPool();
    long start = 0;
    SumTask task;
    long result = 0;
    for (int j = 0 ;j <10;j++) {
        result = 0;
        System.out.println("开始for循环累加计算");
        start = System.currentTimeMillis();
        for(int i = 0;i<300000000;i++){
            result+=datas[i];
        }
        System.out.println("for循环累加计算耗时:"
                +(System.currentTimeMillis()-start)+"\n累加结果:"+result+"\n");

        result = 0;
        System.out.println("开始累加计算");
        start = System.currentTimeMillis();
        task = new SumTask(0,datas.length,datas);
        pool.execute(task);
        result = task.join();
        System.out.println("累加计算耗时:"
                +(System.currentTimeMillis()-start)+"\n累加结果:"+result+"\n");
    }
}

输出结果如下:

开始for循环累加计算
for循环累加计算耗时:166
累加结果:-405325633085518385

开始累加计算
累加计算耗时:117
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:219
累加结果:-405325633085518385

开始累加计算
累加计算耗时:92
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:157
累加结果:-405325633085518385

开始累加计算
累加计算耗时:88
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:160
累加结果:-405325633085518385

开始累加计算
累加计算耗时:94
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:160
累加结果:-405325633085518385

开始累加计算
累加计算耗时:94
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:172
累加结果:-405325633085518385

开始累加计算
累加计算耗时:93
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:158
累加结果:-405325633085518385

开始累加计算
累加计算耗时:97
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:161
累加结果:-405325633085518385

开始累加计算
累加计算耗时:93
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:162
累加结果:-405325633085518385

开始累加计算
累加计算耗时:92
累加结果:-405325633085518385

开始for循环累加计算
for循环累加计算耗时:163
累加结果:-405325633085518385

开始累加计算
累加计算耗时:95
累加结果:-405325633085518385

结果中可以看到,在首次运行速度上比对是,由于Fork/Join框架使用时需要相关线程池以及线程队列、任务队列的初始化,其运行的时间统计要高于后期的耗时,在后续由于相关的线程池以及线程队列、任务队列以及初始化完成,通过对比结果可以看出for循环累加慢于fork/Join任务累加速度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值