Fork/join介绍

Fork/join框架是java7提供的并行执行任务的框架,是把大任务分割成若干小任务,最后汇总若干小任务的执行结果得到最终的结果。它的思想与MapReduce类似。Fork把一个大任务分割成若干小任务,Join用于合并小任务的结果,最后得到大框架的结果。主要采取工作窃取算法。

工作窃取(work-stealing)算法是指某个线程从其它队列窃取任务执行。

假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应,比如A线程负责处理A队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。

工作窃取算法的优点是充分利用线程进行并行计算,并减少了线程间的竞争,其缺点是在某些情况下还是存在竞争,比如双端队列里只有一个任务时。并且消耗了更多的系统资源,比如创建多个线程和多个双端队列。

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

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

核心是两个类:ForkJoinTaskForkJoinPool。Pool主要负责实现,包括上面所介绍的工作窃取算法,管理工作线程和提供关于任务的状态以及它们的执行信息;Task主要提供在任务中,执行Fork与Join操作的机制。

Fork/join代码演示

package com.rumenz.task;import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;public class ForkJoinExample extends RecursiveTask<Integer> {public final static int threshold=2;private int start;private int end;public ForkJoinExample(int start, int end) {this.start = start;this.end = end;}@Overrideprotected Integer compute() {int sum=0;boolean b = (end - start) <= threshold;if(b){//任务足够小的时候,直接计算,不进行分裂计算for (int i = start; i <=end ; i++) {sum+=i;}}else{int mid=(start+end)/2;//继续分裂任务ForkJoinExample task1=new ForkJoinExample(start,mid);ForkJoinExample task2=new ForkJoinExample(mid+1,end);// 执行子任务task1.fork();task2.fork();// 等待任务执行结束合并其结果Integer m = task1.join();Integer n = task2.join();sum=m+n;}return sum;}public static void main(String[] args) throws ExecutionException, InterruptedException {//生成一个池ForkJoinPool forkJoinPool=new ForkJoinPool();ForkJoinTask task=new ForkJoinExample(1, 100000);ForkJoinTask<Integer> submit = forkJoinPool.submit(task);Integer sum = submit.get();System.out.println("最后的结果是:"+sum);}
}

通过这个例子让我们再来进一步了解ForkJoinTask,任务类继承RecursiveTask,ForkJoinTask与一般的任务的主要区别在于它需要实现compute()方法,在这个方法里,首先需要判断任务是否足够小,如果足够小就直接执行任务。如果不足够小,就必须分割成两个子任务,每个子任务在调用fork()方法时,又会进入compute()方法,看看当前子任务是否需要继续分割成孙任务,如果不需要继续分割,则执行当前子任务并返回结果。使用join()方法会等待子任务执行完并得到其结果。

关注微信公众号:【入门小站】,解锁更多知识点

Java中J.U.C扩展组件之Fork,join相关推荐

  1. Java中J.U.C扩展组件之ForkJoinTask和ForkJoinPool

    Fork/Join框架中两个核心类ForkJoinTask与ForkJoinPool,声明ForkJoinTask后,将其加入ForkJoinPool中,并返回一个Future对象. ForkJoin ...

  2. LibreOffice 中的六大实用扩展组件

    LibreOffice 中的六大实用扩展组件 图片来源:Opensource.com LibreOffice 是最好的自由办公套件,并在所有的主要 Linux 发行版中得到应用.尽管 LibreOff ...

  3. 在java中补零的作用是什么_浅谈Java中的补零扩展和补符号位扩展

    今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合. ...

  4. java中j=j++和j=++j的理解

    先来看一段程序: public class Test1 {public static void main(String[] args) {int j = 0;for(int i = 0; i < ...

  5. JAVA中J.U.C 包下并发类的应用

    文章目录 JUC包中的锁应用 Lock接口及ReentrantLock对象分析及应用? Condition接口对象分析与应用? ReadWriteLock接口及实现类分析与应用? StampedLoc ...

  6. Java中J.U.C包下锁的基础-AQS分析

    目录 序言: 1:什么是AQS 2:ReentrantLock(独享式) 3:Semaphore(共享式) 序言: 对于锁的作用,简单保证临界区(多个线程,进程同时访问的区域,最终我们希望只有一个线程 ...

  7. java.util.concurrent 包源码分析之Fork/Join框架

    在JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人理解,有一种分治的策略在里边:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多 ...

  8. java 中j= i_java中 i = i++和 j = i++ 的区别

    由于i++和i--的使用会导致值的改变,所以在处理后置的++和--的时候,java的编译器会重新为变量分配一块新的内存空间,用来存放原来的值, 而完成赋值运算之后,这块内存会被释放. (1)对于j= ...

  9. java中j 和 j啥区别_从字节码层次分析++j和j++的区别

    一.缘起 最近看到个面试题: int j = 0; for(int i = 0; i <100; i++) j = j++; System.out.println(j); 输出结果是0,如果换成 ...

最新文章

  1. pymongo连接mongodb的replset
  2. Dataset之COCO数据集:COCO数据集的简介、下载、使用方法之详细攻略
  3. servlet和webservice+WEBservice 的本质。
  4. VTK:可视化之LabeledMesh
  5. ArrayList刷题总结
  6. Spring集成Mybatis plus
  7. flink中各种图的原理(还没搞完)
  8. Spring AOP方法分析
  9. pl/sql的存储过程
  10. ExtJS应用架构设计(二)
  11. vs2017结合qt开发,vs报错找不到库(解决方案)
  12. ERP天思T8后台SQL批量查询多阶BOM(九层)
  13. 安装智能陈桥五笔时请小心
  14. 秒变“女装大佬”!Snapchat推出性别转换滤镜,离线实时渲染(附测评)
  15. 关于 NM_CONTROLLED和Network Manager
  16. C++, RAII, and the GSL Refresher
  17. VUE3 实现前台图片标注添加矩形框、图片放大、缩小、鼠标滚轮缩放
  18. C语言基础:函数的声明与定义
  19. greendao出现Failed to change locale for db ‘/data/data/xxx/databases/xxx.db‘ to ‘zh_CN‘.
  20. acwing280.陪审团 01背包

热门文章

  1. Oracle 9i for RedHat Linux 的安装
  2. Python实战之多线程编程thread模块
  3. 蓝桥杯 ADV-77 算法提高 统计平均成绩
  4. 蓝桥杯 ALGO-76 算法训练 十进制数转八进制数
  5. 使用MMS(MongoDB Monitoring Service)监控MongoDB
  6. linux之删除vi残留的swp文件
  7. Javascript获取select下拉框选中的的值
  8. AO3414相关技术资料
  9. 96% 移动恶意软件针对 Android 系统:逾50亿应用可被攻击
  10. java学习笔记之斐波那契数列