Java中J.U.C扩展组件之Fork,join
Fork/join
介绍
Fork/join
框架是java7
提供的并行执行任务的框架,是把大任务分割成若干小任务,最后汇总若干小任务的执行结果得到最终的结果。它的思想与MapReduce
类似。Fork
把一个大任务分割成若干小任务,Join
用于合并小任务的结果,最后得到大框架的结果。主要采取工作窃取算法。
工作窃取(work-stealing)算法是指某个线程从其它队列窃取任务执行。
假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应,比如A线程负责处理A队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。
工作窃取算法的优点是充分利用线程进行并行计算,并减少了线程间的竞争,其缺点是在某些情况下还是存在竞争,比如双端队列里只有一个任务时。并且消耗了更多的系统资源,比如创建多个线程和多个双端队列。
对于Fork/Join框架而言,当一个任务正在等待它使用Join操作创建的子任务结束时,执行这个任务的工作线程,寻找其他并未被执行的任务,并开始执行,通过这种方式,线程充分利用它们的运行时间,来提高应用程序的性能。为了实现这个目标,Fork/Join框架执行的任务有一些局限性:
- 任务只能使用Fork、Join操作来作为同步机制,如果使用了其他同步机制,那他们在同步操作时,工作线程则不能执行其他任务。如:在框架的操作中,使任务进入睡眠,那么在这个睡眠期间内,正在执行这个任务的工作线程,将不会执行其他任务
- 所执行的任务,不应该执行IO操作,如读和写数据文件
- 任务不能抛出检查型异常,必须通过必要的代码处理它们
核心是两个类:
ForkJoinTask
与ForkJoinPool
。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相关推荐
- Java中J.U.C扩展组件之ForkJoinTask和ForkJoinPool
Fork/Join框架中两个核心类ForkJoinTask与ForkJoinPool,声明ForkJoinTask后,将其加入ForkJoinPool中,并返回一个Future对象. ForkJoin ...
- LibreOffice 中的六大实用扩展组件
LibreOffice 中的六大实用扩展组件 图片来源:Opensource.com LibreOffice 是最好的自由办公套件,并在所有的主要 Linux 发行版中得到应用.尽管 LibreOff ...
- 在java中补零的作用是什么_浅谈Java中的补零扩展和补符号位扩展
今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合. ...
- java中j=j++和j=++j的理解
先来看一段程序: public class Test1 {public static void main(String[] args) {int j = 0;for(int i = 0; i < ...
- JAVA中J.U.C 包下并发类的应用
文章目录 JUC包中的锁应用 Lock接口及ReentrantLock对象分析及应用? Condition接口对象分析与应用? ReadWriteLock接口及实现类分析与应用? StampedLoc ...
- Java中J.U.C包下锁的基础-AQS分析
目录 序言: 1:什么是AQS 2:ReentrantLock(独享式) 3:Semaphore(共享式) 序言: 对于锁的作用,简单保证临界区(多个线程,进程同时访问的区域,最终我们希望只有一个线程 ...
- java.util.concurrent 包源码分析之Fork/Join框架
在JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人理解,有一种分治的策略在里边:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多 ...
- java 中j= i_java中 i = i++和 j = i++ 的区别
由于i++和i--的使用会导致值的改变,所以在处理后置的++和--的时候,java的编译器会重新为变量分配一块新的内存空间,用来存放原来的值, 而完成赋值运算之后,这块内存会被释放. (1)对于j= ...
- java中j 和 j啥区别_从字节码层次分析++j和j++的区别
一.缘起 最近看到个面试题: int j = 0; for(int i = 0; i <100; i++) j = j++; System.out.println(j); 输出结果是0,如果换成 ...
最新文章
- pymongo连接mongodb的replset
- Dataset之COCO数据集:COCO数据集的简介、下载、使用方法之详细攻略
- servlet和webservice+WEBservice 的本质。
- VTK:可视化之LabeledMesh
- ArrayList刷题总结
- Spring集成Mybatis plus
- flink中各种图的原理(还没搞完)
- Spring AOP方法分析
- pl/sql的存储过程
- ExtJS应用架构设计(二)
- vs2017结合qt开发,vs报错找不到库(解决方案)
- ERP天思T8后台SQL批量查询多阶BOM(九层)
- 安装智能陈桥五笔时请小心
- 秒变“女装大佬”!Snapchat推出性别转换滤镜,离线实时渲染(附测评)
- 关于 NM_CONTROLLED和Network Manager
- C++, RAII, and the GSL Refresher
- VUE3 实现前台图片标注添加矩形框、图片放大、缩小、鼠标滚轮缩放
- C语言基础:函数的声明与定义
- greendao出现Failed to change locale for db ‘/data/data/xxx/databases/xxx.db‘ to ‘zh_CN‘.
- acwing280.陪审团 01背包