一、简介

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

1、ForkJoinPool

既然任务是被逐渐的细化的,那就需要把这些任务存在一个池子里面,这个池子就是ForkJoinPool,它与其它的ExecutorService区别主要在于它使用“工作窃取“,那什么是工作窃取呢?

一个大任务会被划分成无数个小任务,这些任务被分配到不同的队列,这些队列有些干活干的块,有些干得慢。于是干的快的,一看自己没任务需要执行了,就去隔壁的队列里面拿去任务执行。

2、ForkJoinTask

ForkJoinTask就是ForkJoinPool里面的每一个任务。他主要有两个子类:RecursiveAction和RecursiveTask。然后通过fork()方法去分配任务执行任务,通过join()方法汇总任务结果,

这就是整个过程的运用。他有两个子类,使用这两个子类都可以实现我们的任务分配和计算。

(1)RecursiveAction 一个递归无结果的ForkJoinTask(没有返回值)

(2)RecursiveTask 一个递归有结果的ForkJoinTask(有返回值)

ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责存放程序提交给ForkJoinPool的任务,而ForkJoinWorkerThread数组负责执行这些任务。

下面我们就来看看如何去使用。

二、使用

1、RecursiveTask :有返回结果

(1)第一步:创建MyRecursiveTask子类在ForkJoinTest中

    private static class MyRecursiveTask extends RecursiveTask<Integer>{private final int start;private final int end;public MyRecursiveTask(int start, int end) {this.start = start;this.end = end;}@Overrideprotected Integer compute() {//如果任务小的不能再细分了,那就直接计算if(end-start<=threshold) {//rangeClosed包含结束节点,是闭合的return IntStream.rangeClosed(start,end).sum();}else {int mid = (start + end ) /2;MyRecursiveTask leftTask = new MyRecursiveTask(start, mid);MyRecursiveTask rightTask = new MyRecursiveTask(mid+1, end);leftTask.fork();rightTask.fork();return leftTask.join() + rightTask.join() ;}   }}

在这个方法中我们传进去数据,然后使用二分法继续分配给子任务,当任务小的不能再分,那就汇总返回。

(2)第二步在ForkJoinTest中去测试

public class ForkJoinTest {private final static int threshold = 3;public static void main(String[] args) {final ForkJoinPool pool = new ForkJoinPool();ForkJoinTask<Integer> result = pool.submit(new MyRecursiveTask(0, 100));try {System.out.println(result.get());} catch (Exception e) {e.printStackTrace();}}
}

在这个类中我们定义了一个阈值,然后创建一个ForkJoinPool,在这个池子中新建我们刚刚创建的Task任务,最终返回我们结果。

2、RecursiveAction:无返回结果

(1)第一步:创建MyRecursiveAction子类在ForkJoinTest中

    private static class MyRecursiveAction extends RecursiveAction{private final int start;private final int end;  public MyRecursiveAction(int start, int end) {this.start = start;this.end = end;}@Overrideprotected void compute() {//如果任务小的不能再细分了,那就直接计算if(end-start<=threshold) {//rangeClosed包含结束节点,是闭合的sum.addAndGet(IntStream.rangeClosed(start, end).sum());}else {int mid = (start + end ) /2;MyRecursiveTask leftTask = new MyRecursiveTask(start, mid);MyRecursiveTask rightTask = new MyRecursiveTask(mid+1, end);leftTask.fork();rightTask.fork();}}}

在这个方法中我们不需要有return语句。过程和之前的RecursiveTask类似。

(2)第二步在ForkJoinTest中去测试

public class ForkJoinTest {private final static int threshold = 3;private final static AtomicInteger sum = new AtomicInteger(0);public static void main(String[] args) throws InterruptedException {final ForkJoinPool pool = new ForkJoinPool();//注意在这里不需要有返回值了pool.submit(new MyRecursiveAction(0, 100));pool.awaitTermination(100, TimeUnit.MILLISECONDS);//我们依然还可以输出最终的返回值System.out.println(sum);}
}

现在不管我们输出多少次都可以有返回结果了。

ForkJoinTask在执行的时候可能会抛出异常,在主线程中是无法直接获取的,但是可以通过ForkJoinTask提供的isCompletedAbnormally()方法来检查任务是否已经抛出异常或已经被取消了。

java中一个分而治之的框架ForkJoin相关推荐

  1. java 中的fork join框架

    文章目录 ForkJoinPool ForkJoinWorkerThread ForkJoinTask 在ForkJoinPool中提交Task java 中的fork join框架 fork joi ...

  2. Java中常见的日志框架

    可能是太过于常见了,所以使得大家很少关注,只是要用到的时候复制粘贴一份就行,甚至连日志配置文件中的配置语法都不清楚.另外一方面,Java中提供的日志组件太多了,一会儿log4j,一会儿logback, ...

  3. 43、在java中一个类被声明为final类型,表示了什么意思?

    43.在java中一个类被声明为final类型,表示了什么意思? 表示该类不能被继承,是顶级类. JAVA面试问题及答案大全

  4. java类名可以是数字吗_在 Java 中,一个类可同时定义许多同名的方法,这些方法的形式参数的个数、类型或顺序各不相同,传回的值也可以不相同。这种面向对象程序特性称为( )。_学小易找答案...

    [简答题]Java 支持多继承吗 ? [单选题]以下关于继承的叙述正确的是( ). [单选题]在 Java 中,一个类可同时定义许多同名的方法,这些方法的形式参数的个数.类型或顺序各不相同,传回的值也 ...

  5. 在java中使用quartz_如何在Java中使用Quartz Scheduler框架运行cron作业?

    我在Java中使用Quartz Scheduler来运行cron作业 . 这是我第一次使用这个框架来运行cron作业,所以我有些困惑 . 我正在关注这个tutorial以更好地理解如何使用Quartz ...

  6. java切片_ java中一个极其强悍的新特性Stream详解(非常实用)

    java8中有两个非常有名的改进,一个是Lambda表达式,一个是Stream.如果我们了解过函数式编程的话,都知道Stream真正把函数式编程的风格引入到了java中.这篇文章由简入繁逐步介绍Str ...

  7. Java中常见的集合框架及常用的方法

    本篇文章主要说明Java中一些常见的集合框架及经常用到的一些方法 , 由于都是一些父类 , 所以没有做太深入的分析说明 , 后面的文章将会分别对List , Set , Map及其常用子类进行深入研究 ...

  8. Java中一个令人惊讶的bug

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 今天分享一个JDK中令人惊讶的BUG,这个BUG的神奇之处在于,复 ...

  9. java中一个引人深思的匿名内部类

    前两天去面试javaweb问到一个问题,在你的项目中有没有用到线程,我特么的一想,这东西不是在c层面的吗,所以说我不了解线程..... 后来回去想啊想啊,我操这特么的不是再问我事物的控制,消息队列的回 ...

最新文章

  1. MPC8313ERDB不新鲜pkg包裹,把文件放进Ramdisk
  2. [笔记]React+Cordova踩坑
  3. MINA2-TCP服务端实例
  4. 电脑小常识----文件名长度过长解决办法
  5. 听说全链路压测已经杀疯了?劝你别盲目!
  6. C# 整理DotNetBar中SuperGridControl的一些基础属性
  7. LeetCode--434--字符串中的单词数
  8. sql注入 练手网站_靶场sql注入练手----sqlmap篇(纯手打)
  9. Raki的读paper小记:SUBSPACE REGULARIZERS FOR FEW-SHOT CLASS INCREMENTAL LEARNING
  10. Verilog学习之异步复位的串联T触发器设计
  11. EF-EntityFrameWork中文名:实体框架(数据持久化框架)
  12. 洛谷 P1564 膜拜
  13. idea项目误删恢复
  14. 美术集网校—入门学习水彩,刚需教程建议先码后看
  15. 前端将List列表转化为树型结构(reduce函数)
  16. Word控件Spire.Doc 【段落处理】教程(十二):如何在 C# 中管理 word 文档的分页
  17. 论文阅读 Jointly Optimize Data Augmentation and Network Training
  18. 辰奕智能在创业板过会:计划募资约4亿元,约有五成来自境外
  19. IC工程师:百万年薪路上的20个阶段,你在哪个阶段?
  20. 3. 清除浮动的几种方式,及其使用

热门文章

  1. 到底图啥?百度工程师非法控制155台服务器“挖矿”,被判刑3年
  2. 新消费催生新制造:拼多多一年将培育百家销量过亿家纺企业
  3. 微信又干了件大好事 老司机们快看!
  4. 小米618战报出炉!三平台狂揽156项第一
  5. 一辆特斯拉Model S在比利时充电时起火 充电桩也被烧焦
  6. 五一四天假公布后携程机票大涨价 官方如此回应
  7. 程序员为3万福利放弃30万年薪:贪小便宜的人,都把自己坑惨了
  8. 查经 民数记3章 利未人
  9. 定义一个Employee类并排序(完整版本)
  10. 我的docker随笔15:MySQL启动时自动创建数据库