java中一个分而治之的框架ForkJoin
一、简介
从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相关推荐
- java 中的fork join框架
文章目录 ForkJoinPool ForkJoinWorkerThread ForkJoinTask 在ForkJoinPool中提交Task java 中的fork join框架 fork joi ...
- Java中常见的日志框架
可能是太过于常见了,所以使得大家很少关注,只是要用到的时候复制粘贴一份就行,甚至连日志配置文件中的配置语法都不清楚.另外一方面,Java中提供的日志组件太多了,一会儿log4j,一会儿logback, ...
- 43、在java中一个类被声明为final类型,表示了什么意思?
43.在java中一个类被声明为final类型,表示了什么意思? 表示该类不能被继承,是顶级类. JAVA面试问题及答案大全
- java类名可以是数字吗_在 Java 中,一个类可同时定义许多同名的方法,这些方法的形式参数的个数、类型或顺序各不相同,传回的值也可以不相同。这种面向对象程序特性称为( )。_学小易找答案...
[简答题]Java 支持多继承吗 ? [单选题]以下关于继承的叙述正确的是( ). [单选题]在 Java 中,一个类可同时定义许多同名的方法,这些方法的形式参数的个数.类型或顺序各不相同,传回的值也 ...
- 在java中使用quartz_如何在Java中使用Quartz Scheduler框架运行cron作业?
我在Java中使用Quartz Scheduler来运行cron作业 . 这是我第一次使用这个框架来运行cron作业,所以我有些困惑 . 我正在关注这个tutorial以更好地理解如何使用Quartz ...
- java切片_ java中一个极其强悍的新特性Stream详解(非常实用)
java8中有两个非常有名的改进,一个是Lambda表达式,一个是Stream.如果我们了解过函数式编程的话,都知道Stream真正把函数式编程的风格引入到了java中.这篇文章由简入繁逐步介绍Str ...
- Java中常见的集合框架及常用的方法
本篇文章主要说明Java中一些常见的集合框架及经常用到的一些方法 , 由于都是一些父类 , 所以没有做太深入的分析说明 , 后面的文章将会分别对List , Set , Map及其常用子类进行深入研究 ...
- Java中一个令人惊讶的bug
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 今天分享一个JDK中令人惊讶的BUG,这个BUG的神奇之处在于,复 ...
- java中一个引人深思的匿名内部类
前两天去面试javaweb问到一个问题,在你的项目中有没有用到线程,我特么的一想,这东西不是在c层面的吗,所以说我不了解线程..... 后来回去想啊想啊,我操这特么的不是再问我事物的控制,消息队列的回 ...
最新文章
- MPC8313ERDB不新鲜pkg包裹,把文件放进Ramdisk
- [笔记]React+Cordova踩坑
- MINA2-TCP服务端实例
- 电脑小常识----文件名长度过长解决办法
- 听说全链路压测已经杀疯了?劝你别盲目!
- C# 整理DotNetBar中SuperGridControl的一些基础属性
- LeetCode--434--字符串中的单词数
- sql注入 练手网站_靶场sql注入练手----sqlmap篇(纯手打)
- Raki的读paper小记:SUBSPACE REGULARIZERS FOR FEW-SHOT CLASS INCREMENTAL LEARNING
- Verilog学习之异步复位的串联T触发器设计
- EF-EntityFrameWork中文名:实体框架(数据持久化框架)
- 洛谷 P1564 膜拜
- idea项目误删恢复
- 美术集网校—入门学习水彩,刚需教程建议先码后看
- 前端将List列表转化为树型结构(reduce函数)
- Word控件Spire.Doc 【段落处理】教程(十二):如何在 C# 中管理 word 文档的分页
- 论文阅读 Jointly Optimize Data Augmentation and Network Training
- 辰奕智能在创业板过会:计划募资约4亿元,约有五成来自境外
- IC工程师:百万年薪路上的20个阶段,你在哪个阶段?
- 3. 清除浮动的几种方式,及其使用