六问六答理解ForkJoin原理
摘要:ForkJoin线程池是将任务分割为子任务,有可能子任务还是很大,还需要进一步拆解,最终得到足够小的任务。
本文分享自华为云社区《ForkJoin线程池的学习和思考》,作者:breakDraw。
ForkJoin线程池在常规的java书籍里还是提到比较少的,毕竟是java8引入的产物。
首先这里简单解释一下forkJoin的运作原理, 本质上有点像归并计算。
- 他会将提交大任务按照一定规则拆解(fork)成多个小任务
- 当任务小到一定程度时,就会执行计算
- 执行完成时会和其他的小任务进行合并(join), 逐步将所有小结果合成一个大结果。
可以看这个forkJoinTask的实现伪代码,即如果想使用forkJoin并发执行任务,需要自己把任务继承RecursiveTask,作为forkJoin池的submit对象:
public class ForkJoinTask extends RecursiveTask<任务参数> {
public ReckonTask(任务参数) { } @Override
protected File compute() {
if(根据任务参数判断任务是否足够小) {
计算,返回
} else {
拆分成子任务1和子任务2
任务1.fork();
任务2.fork();
结果1 = 任务1.join();
结果2 = 任务2.join();
返回结果1+结果2;
}
}
}
然后实际上整个forkjoin的细节非常多,这里我通过给自己提好几个问题,来逐步理解forkJoin的原理:
Q: forkJoin中各个线程是如何获取那些小任务的呢?
A:他是通过工作密取的方式获取。(java并发那本书里提到过工作密取workSteal,原来是用在这了)
- 假设我们给forkJoin设置3个工作线程,那么就会有3个工作队列, 注意,这个队列是双端队列。
- 每当执行任务时,如果不满足小任务的条件,他会fork出2个子任务,并push进自己的工作队列中。
- 每个工作线程不断取自己队头的任务执行。
- 关键点:如果自己队列里没有数据,则会从其他队列的队尾取数据。
Q: fork时具体发生了什么?
A:是一个异步的操作, 就是向当前线程队列中添加这个fork出来任务,能放进去的话就返回,不会等待。
注意,默认fork出的任务是先默认给自己的。 当自己做不完时,才可能被别人取走!
Q: join是什么含义?什么时候做的?
A:见实现forkJoin任务接口时的代码:
可以看到时每次fork完之后, 通过join,来获取子task的结果,获取到之后,再合并计算,返回结果。
Q: join这个阻塞过程是怎么做的?如果把线程挂起,那这个线程岂不是无法工作了?
A:首先,之前fork时,新的子任务已经被放入队列了。
每个子任务都有一个任务状态。
当调用该子任务的join时, 会循环判断他的状态
如果这个子任务状态未完成, 则从自身队列或其他人的队列中取出新的任务执行,因此进入了下一层的exec()操作。
如果发现子任务状态更新为了完成(这个更新动作可能是自己线程完成的,也可能是别的线程完成的,反正这个任务的状态实现了同步和可见), 则将结果返回给上层。
因此join的本质是一个递归的过程, 任务没完成的话,他就取其他任务继续递归往下执行。
更详细的可以看这个链接fork+join过程详细解读
Q: forkJoin存放任务的时候,怎么保证不会出现并发问题?比如同时往队尾插入的话
A:
- n个工作线程是通过数组存放的(即有一个工作线程数组)
- sun.misc.Unsafe操作类直接基于操作系统控制层在硬件层面上进行原子操作,它是ForkJoinPool高效性能的一大保证,类似的编程思路还体现在java.util.concurrent包中相当规模的类功能实现中。
Q: forkJoin应用在哪吗?
A:java8 stream的parallel并发功能就是基于forkJoin做的, parallelStream实现的forkJoin拆解任务和执行任务的接口, 默认用机器所有CPU数量的forkJoin线程池。
如果需要限制线程数量,可以用
new forkJoin(线程数).submit(()->(list.stream().parallel().map()…)); 即可
六问六答理解ForkJoin原理的更多相关文章
- exec 跟 source 差在哪?-- Shell十三问<第六问>
exec 跟 source 差在哪?-- Shell十三问<第六问> 这次先让我们从 CU Shell 版的一个实例贴子来谈起吧: 例中的提问是: cd /etc/aa/bb/cc 可以执 ...
- 拜托!面试请不要再问我Spring Cloud底层原理[z]
[z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...
- 《深入理解mybatis原理》 MyBatis的架构设计以及实例分析
作者博客:http://blog.csdn.net/u010349169/article/category/2309433 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简 ...
- k3 Bos开发百问百答
K/3 BOS开发百问百答 (版本:V1.1) K3产品市场部 目录 一.基础资料篇__ 1 [摘要]bos基础资料的显示问题_ 1 [摘要]单 ...
- 《深入理解mybatis原理3》 Mybatis数据源与连接池
<深入理解mybatis原理> Mybatis数据源与连接池 对于ORM框架而言,数据源的组织是一个非常重要的一部分,这直接影响到框架的性能问题.本文将通过对MyBatis框架的数据源结构 ...
- 《深入理解mybatis原理1》 MyBatis的架构设计以及实例分析
<深入理解mybatis原理> MyBatis的架构设计以及实例分析 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构 ...
- 第九节: 利用RemoteScheduler实现Sheduler的远程控制 第八节: Quartz.Net五大构件之SimpleThreadPool及其四种配置方案 第六节: 六类Calander处理六种不同的时间场景 第五节: Quartz.Net五大构件之Trigger的四大触发类 第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联
第九节: 利用RemoteScheduler实现Sheduler的远程控制 一. RemoteScheduler远程控制 1. 背景: 在A服务器上部署了一个Scheduler,我们想在B服务器上 ...
- Java 面试题问与答:编译时与运行时
Java 面试题问与答:编译时与运行时 2012/12/17 | 分类: 基础技术, 职业生涯 | 5 条评论 | 标签: RUNTIME, 面试 分享到:58 本文作者: ImportNew - 朱 ...
- OpenGL快问快答
OpenGL快问快答 本文内容主要来自对(http://www.opengl.org/wiki/FAQ)的翻译,随机加入了本人的观点.与原文相比,章节未必完整,含义未必雷同,顺序未必一致.仅供参考. ...
随机推荐
- contos 安装 nginx
参考链接https://blog.csdn.net/u011159417/article/details/80081992 https://blog.csdn.net/wangxy_job/artic ...
- Composer基础
摘要 本文介绍Composer的入门知识,包括require和autoload部分. Java有Maven, Node.js有npm, ROR有gem, 这些语言的程序员在开心地使用包管理工具加速开发 ...
- P4022-[CTSC2012]熟悉的文章【广义SAM,dp,单调队列】
正题 题目链接:https://www.luogu.com.cn/problem/P4022 题目大意 给出\(m\)个模板串. 然后\(n\)次询问给出一个串\(S\)要求找到一个最大的\(L\)使 ...
- P4831-Scarlet loves WenHuaKe【组合数学】
正题 题目链接:https://www.luogu.com.cn/problem/P4831 题目大意 \(n*m\)的网格上放置\(2n\)个炮,要求互不能攻击. 数据满足\(n\leq m\leq ...
- P4774-[NOI2018]屠龙勇士【EXCRT】
正题 题目链接:https://www.luogu.com.cn/problem/P4774 题目大意 \(n\)个龙血量为\(a_i\),回复能力为\(p_i\),死亡后掉落剑的攻击力\(t_i\) ...
- bootstrap inputfile 使用-上传,回显
近期用bootstrap 做前端的上传,功能涉及到上传时就是召网上的教程随便弄一搜一大把,但是做到修改页面时候不知道页面该如何回显,折腾了一阵子才完成遂记录下来希望能给看到的小伙伴有点启发吧. 首先是 ...
- vector 的交换技巧
面试被问到如何解决 vector 有过多空闲内存的问题. 假定先有一 vector 容器 vec,它的容量是 10000,大小是 3. vector 的内存增长问题 vector 申请的是连续内存空间 ...
- 国庆出游神器:魔幻黑科技换天造物,让vlog秒变科幻大片!
摘要:国庆旅游景点人太多,拍出来的照片全是人人人.车车车,该怎么办?不妨试试这个黑科技,让你的出游vlog秒变科幻大片. 本文分享自华为云社区<国庆出游神器,魔幻黑科技换天造物,让vlog秒变科 ...
- 4.自定义类加载器实现及在tomcat中的应用
了解了类加载器的双亲委派机制, 也知道了双亲委派机制的原理,接下来就是检验我们学习是否扎实了,来自定义一个类加载器 一. 回顾类加载器的原理 还是这张图,类加载器的入口是c++调用java代码创建了J ...
- mysql从零开始之MySQL DELETE 语句
MySQL DELETE 语句 你可以使用 SQL 的 DELETE FROM 命令来删除 MySQL 数据表中的记录. 你可以在 mysql> 命令提示符或 PHP 脚本中执行该命令. 语法 ...