Fork/Jion框架详解

Fork/Jion框架可以干什么

如果你要处理1万条数据,但是你的能力暂时还不够,一个简单快捷的办法就是你可以把每次只处理100条,等到处理100次之后再把所有的结果聚合起来你就处理完了这1万条数据。

Fork/Join就是是Java7提供的原生多线程并行处理框架,它的基本思想就是将大任务分割成小任务,最后将小任务聚合起来得到结果。

如何使用Fork/Jion框架

我们要使用ForkJoin框架,首先要创建一个ForkJoin任务。它提供在任务中执行fork()和join的操作机制。

fork用来创建子线程,可以让程序多一个执行分枝,jion在我们之前文章中已经提到了,那就是等待结果。

通常我们可以按需继承如下两个类来使用Fork/Jion框架:

 

    1. RecursiveAction,用于没有返回结果的任务

 

    2. RecursiveTask,用于有返回值的任务

 

代码示例

下方是一个使用Fork/Jion框架计算1到10000的所有数值的和的一个简单的代码示例:

public class ForkJionDemo extends RecursiveTask<Integer> {	
    //任务拆分阈值	
    public static final int threshold = 100;	
    //计算起始值	
    private int start;	
    //计算结束值	
    private int end;	

	
    public ForkJionDemo(int start, int end) {	
        this.start = start;	
        this.end = end;	
    }	

	
    @Override	
    protected Integer compute() {	
        int sum = 0;	
        //计算任务是否需要拆分	
        boolean canCompute = (end - start) <= threshold;	
        if (canCompute) {	
            //无需拆分则执行任务累计	
            for (int i = start; i <= end; i++) {	
                sum += i;	
            }	
        } else {	
            List<ForkJionDemo> forkJionDemoList=new ArrayList<>();	
            //将任务拆分成100份	
            for(int i=0;i<100;i++){	
                //计算这个一份任务要计算的起点和终点,如果终点大于最大值则使用最大值为终点	
                int last=(start+threshold)>end?end:(start+threshold);	
                ForkJionDemo forkJionDemo = new ForkJionDemo(start, last);	
                //下一份任务的起点要更新	
                start+=threshold+1;	
                forkJionDemoList.add(forkJionDemo);	
                //提交子任务	
                forkJionDemo.fork();	
            }	
            //汇总拆分完毕后的任务结果	
            for(ForkJionDemo forkJionDemo:forkJionDemoList){	
                sum  += forkJionDemo.join();	
            }	
        }	
        return sum;	
    }	

	
    public static void main(String[] args) {	
        //构造一个任务线程池	
        ForkJoinPool forkjoinPool = new ForkJoinPool();	
        //创建一个计算1到10000之间所有数的和的任务	
        ForkJionDemo forkJionDemo = new ForkJionDemo(1, 10000);	
        //将任务提交到任务线程池	
        Future<Integer> result = forkjoinPool.submit(forkJionDemo);	
        try {	
            //打印最后计算结果	
            System.out.println(result.get());	
        } catch (InterruptedException e) {	
            e.printStackTrace();	
        } catch (ExecutionException e) {	
            e.printStackTrace();	
        }	
    }	
}

使用Fork/Jion框架需要注意的点

如果使用Fork/Jion框架计算的任务量特别庞大时很可能会出现以下2种情况:

  1. fork的线程越来越多导致性能严重下降

  2. 函数调用层次越来越深导致栈溢出

640?wx_fmt=gif

640?wx_fmt=jpeg

 收藏转发好看再走呗!

640?wx_fmt=gif
 

点击下方“阅读原文”查看源码!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值