ForkJoin框架是Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

与MapReduce思想非常类似。从字面意思上看,Fork就是把一个大任务切割成若干个子任务并行执行,Join就是合并这些子任务的执行结果,最后得到大任务的结果。主要采用工作窃取算法。

工作窃取算法是指某个线程从其他队列里窃取任务来执行。下面是工作窃取的流程图:

为什么要使用工作窃取算法?

加入我们需要做一个比较大的任务,我们可以把这个任务分割成若干个互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,为每个队列创建一个单独的线程来执行队列里面的任务,线程和队列一一对应。比如A线程负责处理A队列里面的任务,但是有些线程会先把自己的队列里面的任务干完,而其他线程还有对应的任务等待处理,干完活的线程就会帮其他线程干活,于是就会去其他线程的队列里窃取一个任务来执行,这时他们会访问同一个队列,所以为了减少窃取任务线程与被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务的线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。这种优点就是充分利用线程进行并行计算,减少了线程间的竞争,缺点是在某些情况下还是存在竞争(比如在双端队列只有一个任务时),同时也消耗了更多的系统资源(比如创建了多个线程和多个双端队列)。

对于ForkJoin框架而言,当一个任务正在等待他使用ForkJoin操作创建的子任务结束时,执行这个任务的工作线程查找其他未被执行的任务,并开始他的执行,通过这种方式,线程充分利用他的运行时间来提高应用程序的性能,为了实现这个目标ForkJoin框架执行的任务有一些局限性。

局限性

  • 任务只能使用Fork和Join操作来作为同步机制,如果使用了其他同步机制,那他们在同步操作时工作线程就不能执行其他任务了。比如在forkjoin框架中使任务进入sleep,在睡眠期间内正在执行这个任务的工作线程将不会执行其他任务了。
  • 我们所拆分的任务不应该去执行IO操作。例如读写数据文件
  • 任务不能抛出检查异常。必须通过必要的代码来处理他们

ForkJoin框架的核心是两个类:ForkJoinPool和ForkJoinTask。ForkJoinPool负责做实现(包括工作窃取算法)他管理工作线程提供任务的状态以及他们的执行信息。而ForkJoinTask则主要提供在任务中执行Fork和Join操作的机制。

@Slf4j
public class ForkJoinTaskExample extends RecursiveTask<Integer> {public static final int threshold = 2;private int start;private int end;public ForkJoinTaskExample(int start, int end) {this.start = start;this.end = end;}@Overrideprotected Integer compute() {int sum = 0;//如果任务足够小就计算任务boolean canCompute = (end - start) <= threshold;if (canCompute) {for (int i = start; i <= end; i++) {sum += i;}} else {// 如果任务大于阈值,就分裂成两个子任务计算int middle = (start + end) / 2;ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end);// 执行子任务leftTask.fork();rightTask.fork();//等待任务执行结束合并其结果int leftResult = leftTask.join();int rightResult = rightTask.join();// 合并子任务sum = leftResult + rightResult;}return sum;}public static void main(String[] args) {ForkJoinPool forkJoinPool = new ForkJoinPool();//生成一个计算任务,计算1+2+3+4...+100ForkJoinTaskExample taskExample = new ForkJoinTaskExample(1, 100);Future<Integer> result = forkJoinPool.submit(taskExample);try{log.info("result:{}", result.get());} catch (InterruptedException e) {log.error("exception", e);e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}

java高并发(十六)J.U.C之ForkJoin相关推荐

  1. java高并发(六)线程安全性

    定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 线程安全性 ...

  2. Java高并发(六)——ThreadLocal为线程保驾护航

    前边我们讲述多线程交互,多线程引起的安全问题,多线程安全的问题解决同步(synchronized.lock.CAS)--这一切的一切起源就是共享资源,共享临界区的数据安全引起的.那我们从另外一个角度想 ...

  3. 《实战Java高并发程序设计》读后感

    写在前面无关的内容 白驹过隙,看下日历已经毕业4年多,加上在大学里的4年,算算在计算机界也躺了八年,按照格拉德韦尔的1万小时定律差不多我也该成为行业的专家了,然后并没有.当看着"什么是Jav ...

  4. java高并发与多线程汇总(一):基础知识(上)

    java高并发与多线程汇总 往期文章推荐:   java高并发与多线程汇总(一):基础知识(上)   java常见面试考点(四十二):序列化与反序列化   java常见面试考点(四十三):泛型   j ...

  5. cpu高 thread vm_阿里大佬总结,Java高并发必读!

    作者:wxdoop 原文:https://blog.csdn.net/qq_36235098 来源:前程有光 前言 进程是计算机中程序关于某几何数据集合上的一次运行活动,是系统进行资源分配和调度的基本 ...

  6. Java 高并发_JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 没有项目经验的朋友不要错过!...

    JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 没有项目经验的朋友不要错过! 1.JPG (37.82 KB, 下载次数: 0) 2018-12-3 09:40 上传 2.JPG (28 ...

  7. java高并发(一)导学

    现在准备系统学习java高并发与多线程相关知识. 首先了解一下我们这一套知识的学习思路: 并发与高并发相关概念 CPU多级缓存 缓存一致性 乱序执行优化 java内存模型 JMM规定.抽象结构 同步操 ...

  8. Java高并发编程详解系列-Java线程入门

    根据自己学的知识加上从各个网站上收集的资料分享一下关于java高并发编程的知识点.对于代码示例会以Maven工程的形式分享到个人的GitHub上面.   首先介绍一下这个系列的东西是什么,这个系列自己 ...

  9. java高并发系列 - 第1天:必须知道的几个概念

    java高并发系列-第1天:必须知道的几个概念 同步(Synchronous)和异步(Asynchronous) 同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后, ...

  10. Java高并发编程 (马士兵老师视频)笔记(一)同步器

    本篇主要总结同步器的相关例子:包括synchronized.volatile.原子变量类(AtomicXxx).CountDownLatch.ReentrantLock和ThreadLocal.还涉及 ...

最新文章

  1. 使用yum管理软件包
  2. linux查看机器品牌信息,dmidecode查看linux硬件信息
  3. C/C++:Windows编程—IAT Hook实例(程序启动拦截)
  4. tcpdump 不显示指定ip_wordpress首页不显示指定分类文章的方法
  5. 用计算机里可以加50度电,一台电脑一天用多少度电 节电节能的建议和措施
  6. 数据提取软件----GetData
  7. 微软sql服务器可以卸载,完美卸载SQL Server 2008的方法
  8. 如何通过注册表修改默认程序
  9. TunesKit Video Cutter for mac(视频分割编辑器)
  10. Android WebView优化
  11. 一个完全免费的在线文字云网站
  12. 基于FBX SDK的FBX模型解析与加载
  13. Android 集成支付宝支付
  14. android9 三星 港版,三星S9官方港版安卓9固件系统升级更新包:TGY-G9600ZHU5CSFB
  15. 2.25亿个邮箱密码被盗、微软漏洞或致黑客接管域控制器|12月23日全球网络安全热点
  16. 记一次搭建 nodebb 论坛
  17. 两行代码激活windows系统
  18. Leetcode——507. Perfect Number
  19. 【智能门禁系统设计】——项目需求分析(门禁终端软件)
  20. 用C语言实现简单的计算器

热门文章

  1. php 获取时间段 今天昨天本周上周本月上月本季度本年去年
  2. 为什么非全站升级HTTPS不可?
  3. php怎么输出mysql一条数据,MySQL数据输出在一个可打印的PHP变量
  4. java多线程遇到的问题_关于Java多线程遇到的问题.
  5. Java异常日志的查询语句_java学习异常,断言和日志
  6. python中索引是从什么开始_python索引从0开始,那负数索引算什么?三秋道果说python...
  7. 仿京东左侧菜单弹出html代码,相仿京东左侧菜单
  8. 错误:未在本地计算机上注册“Microsoft.Ace.OleDb.12.0”提供程序
  9. 【SpringBoot】【Thyemeleaf 】【Spring EL表达式】 SPEL调用静态类、静态方法
  10. idea没有RunDashboard解决办法