Java并发基础-Fork、Join方式的并行计算研究分析

本文目录:

1 Fork/Join概述

Fork/Join是JDK中提供的类似Map/Reduce的并行计算的实现;它主要处理那些可以递归的分解成更小作业的作业。
与Map/Reduce类似,它也分成两个过程:
- Fork:大的作业被分成很多小的作业分别提交到线程池中执行; 
- Join:小作业完成后通过Join操作合并每个作业的执行结果;

示例 假设有10000个数据要计算其合计值,那么我们可以将这10000个数分成100个作业,每个作业执行100个数据的合计值;这100个作业被提交到线程池中并行运行;这就是Fork的过程。
每个小作业执行会有一个结果,Join就是负责将这100个作业的执行结果合并起来。

Fork/Join采用工作窃取算法业充分利用每个线程;每个线程可能被分配多个任务;当分配给某个线程的任务全部执行完成时,它将会窃取原本分配给其它线程的任务并执行,这样能尽量提高计算效率。

说明 关于工作窃取,按上面所述的10000个数的计算操作,也可以这样理解:A线程被分配了100个数据的计算任务,这100个数的任务又可能被细分成更小粒度的10个数的计算任务;这些子任务都是分配给A来执行的;假设分配给另外的B线程的任务已经执行完成,而A中还剩下有子任务未执行完成,那B会从A的队列中取得未执行的子任务来执行。

Fork/Join计算框架的核心是ForkJoinPool这个类,它继承自AbstractExecutorService类,实现了工作窃取算法。而ForkJoinTask的任务可以被提交到ForkJoinPool中执行。

2 示例

先以一简单的例子来说明Fork/Join如何使用。
以第一节中所述的例子来演示,计算10000个数的和。

public static void main(String[] args) {
    //生成10000个随机数
    List<Integer> list = Stream.generate(() -> (int)(Math.random() * 10)).limit(10000)
    .collect(Collectors.toList());

    //创建ForkJoinTask对象
    ForkJoinTask<Integer> forkJoinTask = new MyForkJoinTask(list);

    //提交到ForkJoinPool中
    ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
    Integer result = forkJoinPool.invoke(forkJoinTask);

    //比较计算结果与Stream的计算结果是否一致
    System.out.println(result + ", " + list.stream().reduce((x, y) -> x + y).get());
}

/**
 * 并行计算传入的List中所有元素的和
 */
public static class MyForkJoinTask extends ForkJoinTask<Integer>{
   
    private int result = 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值