摘要:框架框架简介框架是提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果得到大任务结果的框架。框架实例需求计算的结果。
Fork/Join框架 1. Fork/Join框架简介
Fork/Join框架是java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果得到大任务结果的框架。Fork指的就是把一个大任务分割成若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。
比如计算1+2+3+4+5+……+10000,可以分割成10个子任务,每个子任务负责分别对1000个数进行求和,最终汇总这10个子任务的结果。
2. Fork/Join框架使用说明使用Fork/Join框架我们需要两个类:
ForkJoinTask:Fork/Join任务,提供fork()和Join()方法,通常情况下继承它的两个子类:
RecursiveAction:返回没有结果的任务。
RecursiveTask:返回有结果的任务。
ForkJoinPool:ForkJoinTask需要通过ForkJoinPool来执行。
从ForkJoinTask的两个子类的名字中就可以看到,这是一种采用递归方式实现的任务分割,任务分割的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部,当一个工作线程的队列里面暂时没有任务时,它会随机从其他工作线程队列的尾部获取一个任务去执行。
3. Fork/Join框架实例 3.1 需求:计算1 + 2 + 3 +……+10 的结果。
3.2 需求分析设计:使用Fork/Join框架首先要考虑的就是如何分割任务,和分割任务的粒度,这里我们考虑每个子任务最多执行两个数相加,那我们分割的阈值就是2,Fork/Join框架会把这个任务fork成5个子任务,然后再join5个子任务的结果。因为是有结果的任务,所以必须继承RecursiveTask。
3.3 代码实例package com.wangjun.thread; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; public class ForkJoinTaskTest extends RecursiveTask{ private static final int THRESHOLD = 2; // 阈值 private int start; private int end; public ForkJoinTaskTest(int start, int end) { this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; if(end - start < THRESHOLD) { System.out.println(Thread.currentThread().getName() + ":" + start + "-" + end); for(int i = start; i <= end; i++) { sum += i; } }else { // 任务大于阈值,拆分子任务 int middle = start + (end - start)/2; ForkJoinTaskTest task1 = new ForkJoinTaskTest(start, middle); ForkJoinTaskTest task2 = new ForkJoinTaskTest(middle + 1, end); // 执行子任务 task1.fork(); task2.fork(); // 等待子任务执行完成,并得到其结果 int result1 = task1.join(); int result2 = task2.join(); // 合并子任务 sum = result1 + result2; } return sum; } public static void main(String[] args) throws InterruptedException, ExecutionException { int start = 1; int end = 10; ForkJoinTaskTest task = new ForkJoinTaskTest(start, end); // 用来执行ForkJoinTask ForkJoinPool pool = new ForkJoinPool(); // 执行任务 Future result = pool.submit(task); System.out.println("最后的结果为:" + result.get()); } }
运行结果:
ForkJoinPool-1-worker-2:3-3 ForkJoinPool-1-worker-0:4-5 ForkJoinPool-1-worker-3:6-7 ForkJoinPool-1-worker-1:1-2 ForkJoinPool-1-worker-3:8-8 ForkJoinPool-1-worker-0:9-10 最后的结果为:55
可以看到ForkJoinTask与一般的任务在于它需要实现compute()方法,在这个方法里面首先需要判断是否需要分割子任务,如果需要分割,每个子任务再调用fork方法时,就会进入compute()方法,如果不需要分割,则执行当前任务并返回结果,使用join方法会等待子任务结果的返回。可以看到这是一种递归的实现。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69619.html
摘要:第二步执行任务并合并结果。使用两个类来完成以上两件事情我们要使用框架,必须首先创建一个任务。用于有返回结果的任务。如果任务顺利执行完成了,则设置任务状态为,如果出现异常,则纪录异常,并将任务状态设置为。 1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的...
摘要:对于任务的分割,要求各个子任务之间相互独立,能够并行独立地执行任务,互相之间不影响。是叉子分叉的意思,即将大任务分解成并行的小任务,是连接结合的意思,即将所有并行的小任务的执行结果汇总起来。使用方法会阻塞并等待子任务执行完并得到其结果。 Fork/Join是什么? Fork/Join框架是Java7提供的并行执行任务框架,思想是将大任务分解成小任务,然后小任务又可以继续分解,然后每个小...
摘要:同时,它会通过的方法将自己注册到线程池中。线程池中的每个工作线程都有一个自己的任务队列,工作线程优先处理自身队列中的任务或顺序,由线程池构造时的参数决定,自身队列为空时,以的顺序随机窃取其它队列中的任务。 showImg(https://segmentfault.com/img/bVbizJb?w=1802&h=762); 本文首发于一世流云的专栏:https://segmentfau...
摘要:为了减少窃取线程和别窃取线程之间的竞争我们通常使用双端队列。被窃取线程永远从双端队列的头部获取任务,窃取线程永远从双端队列的尾部获取内容。优点就是充分利用线程进行并行计算,减少线程间的竞争。使用操作的线程不能执行操作。 Fork-Join框架 Fork和Join是java 1.7提供的用于定型执行的框架,将大任务切分成若干个小任务执行,小任务执行结果汇总成大任务的框架。从字面上理解就是...
摘要:并不会为每个任务都创建工作线程,而是根据实际情况构造线程池时的参数确定是唤醒已有空闲工作线程,还是新建工作线程。 showImg(https://segmentfault.com/img/bVbiYSP?w=1071&h=707); 本文首发于一世流云的专栏:https://segmentfault.com/blog... 一、引言 前一章——Fork/Join框架(1) 原理,我们...
阅读 2663·2023-04-25 14:59
阅读 855·2021-11-22 11:59
阅读 602·2021-11-17 09:33
阅读 2416·2021-09-27 13:34
阅读 3845·2021-09-09 11:55
阅读 2291·2019-08-30 15:44
阅读 1100·2019-08-30 14:06
阅读 1890·2019-08-29 16:55