Fork/Join 框架
来源:互联网 发布:掌上电力显示网络异常 编辑:程序博客网 时间:2024/04/28 10:04
ForkJoin 将大任务分割成小任务,若子任务还不够小则继续分割,最后执行任务合并结果。
- ForkJoinTask: 我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。他提供了在任务中执行fork()和join()操作机制。RecursiveTask有返回值的子类RecursiveAction 没有返回值的之类。
- ForkJoinPool :ForkJoinTask需要使用ForkJoinPool 来执行。
举例:下面计算1+2+3+…+9+10
每个子任务计算三个数相加
package com.john;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.Future;import java.util.concurrent.RecursiveTask;public class ForkJoinTest {//其中RecursiveTask<Integer>时ForkJoin实现类,直接继承即可。//若子任务是没有返回值的则直接继承RecursiveAction 实现类。 public class CountTask extends RecursiveTask<Integer>{ private int s; private int e; private final static int THRESHOLD=3; public CountTask(int s,int e) { this.s=s; this.e=e; } @Override protected Integer compute() { int ret=0; //每个子任务计算三个数相加 if(e-s>THRESHOLD) { int mid=(s+e)/2; CountTask left=new CountTask(s, mid); CountTask right=new CountTask(mid+1, e); left.fork(); right.fork(); //取得子任务的结果并合并结果 int l=left.join(); int r=right.join(); ret=l+r; } else{ for(int i=s;i<=e;i++) { ret+=i; } } System.out.println("当前线程名:"+Thread.currentThread().getName()+" 计算从"+s+"到"+e+"的结果为:"+ret); return ret; } } public static void main(String[] args) throws InterruptedException, ExecutionException { ForkJoinPool pool=new ForkJoinPool(); ForkJoinTest test=new ForkJoinTest(); CountTask c=test.new CountTask(1, 10); Future<Integer> future=pool.submit(c); System.out.println(future.get().intValue()); }}
输出结果:当前线程名:ForkJoinPool-1-worker-1 计算从1到3的结果为:6当前线程名:ForkJoinPool-1-worker-0 计算从9到10的结果为:19当前线程名:ForkJoinPool-1-worker-2 计算从6到8的结果为:21当前线程名:ForkJoinPool-1-worker-2 计算从6到10的结果为:40当前线程名:ForkJoinPool-1-worker-3 计算从4到5的结果为:9当前线程名:ForkJoinPool-1-worker-1 计算从1到5的结果为:15当前线程名:ForkJoinPool-1-worker-1 计算从1到10的结果为:5555
Fork/Join如何处理异常?
task.isCompletedAbnormally()用于判断任务是否有异常,若有,可以使用task.getException()获得异常信息。
实现原理:
ForkJoinTask 的fork()原理:
public final ForkJoinTask<V> fork() { Thread t; if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) //push()将ForkJoinTest 压入队列,然后调用ForkJoinPool的singalWork()来唤醒或创建一个工作线程 ((ForkJoinWorkerThread)t).workQueue.push(this); else ForkJoinPool.common.externalPush(this); return this; }
ForkJoinTask的join()方法原理
public final V join() { int s; if ((s = doJoin() & DONE_MASK) != NORMAL) reportException(s); return getRawResult(); } //首先查看任务状态,若任务执行完成,直接返回结果,若为执行完,则从任务数组中取出并执行,若跑出异常,则记录异常,并将任务状态设置为EXCEPTIONAL private int doJoin() { int s; Thread t; ForkJoinWorkerThread wt; ForkJoinPool.WorkQueue w; return (s = status) < 0 ? s : ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ? (w = (wt = (ForkJoinWorkerThread)t).workQueue). tryUnpush(this) && (s = doExec()) < 0 ? s : wt.pool.awaitJoin(w, this) : externalAwaitDone(); }
0 0
- Fork/Join框架之Fork、Join操作
- Fork/Join框架之Fork、Join操作
- Fork/Join框架之Fork、Join操作
- Fork/Join框架介绍
- Fork/Join框架介绍
- java Fork-join框架
- Fork/Join框架介绍
- Java7 FORK/JOIN框架
- Fork/Join框架
- Fork/Join框架简介
- Fork/Join框架使用
- Fork/Join 框架
- fork/join框架
- Java Fork/join框架
- Fork/Join框架介绍
- Fork/Join框架简介
- Fork/Join框架介绍
- JAVA Fork/Join 框架
- 科大讯飞之Comparator比较器
- 项目作品地址
- M051定时器
- iOS开发之可双向调节的Slider滑块
- session和cookie的深入认识
- Fork/Join 框架
- caffe windows10 vs2013 安装配置 GPU版本CPU也可参考
- jquery各种选择器
- hdu 1166 士兵杀敌 【线段树】
- 如何通过配置log4j.xml来打印指定类或指定级别的日志信息
- Linux系统安装分区方式
- Linux Input子设备event事件解析器Analyzer
- Windows和Mac环境下的sublime快捷键
- 关于listview的复用机制