在JDK1.7版本中提供了Fork-Join并行执行任务框架,它的主要作用是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总,这种开发方法也叫做分治编程,可以极大地利用CPU资源,提高任务执行的效率。

使用RecursiveAction分解任务

public class MyRecursiveAction extends RecursiveAction {

	private int beginValue;
private int endValue; public MyRecursiveAction(int beginValue, int endValue) {
super();
this.beginValue = beginValue;
this.endValue = endValue;
}
@Override
protected void compute() {
System.out.println("MyRecursiveAction.compute()----" + Thread.currentThread().getName());
if (endValue - beginValue > 2) {
int middleValue = (beginValue + endValue)/2;
MyRecursiveAction leftAction = new MyRecursiveAction(beginValue, middleValue);
MyRecursiveAction rightAction = new MyRecursiveAction(middleValue + 1, endValue);
invokeAll(leftAction, rightAction);
} else {
System.out.println("组合result:" + beginValue + "--" + endValue);
}
}
} public class Main {
public static void main(String[] args) throws InterruptedException {
ForkJoinPool pool = new ForkJoinPool();
pool.submit(new MyRecursiveAction(1, 10));
Thread.sleep(5000);
}
}

控制台输出结果如下:

MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
组合result:1--3
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
组合result:4--5
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
组合result:6--8
MyRecursiveAction.compute()----ForkJoinPool-1-worker-1
组合result:9--10

使用RecursiveTask取得返回值

public class MyRecursiveTask extends RecursiveTask<Integer> {

	@Override
protected Integer compute() {
System.out.println("Time:" + System.currentTimeMillis());
return 100;
}
} public class Test1 {
public static void main(String[] args) {
try {
MyRecursiveTask task1 = new MyRecursiveTask();
System.out.println(task1.hashCode());
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Integer> task2 = pool.submit(task1);
System.out.println(task2.hashCode() + " " + task2.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}

程序输出结果如下:

1311053135
Time:1473599556598
1311053135 100

也可以使用join()方法取得返回值

public class Test2 {
public static void main(String[] args) {
try {
MyRecursiveTask task1 = new MyRecursiveTask();
System.out.println(task1.hashCode());
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Integer> task2 = pool.submit(task1);
System.out.println(task2.hashCode() + " " + task2.join());
} catch (Exception e) {
e.printStackTrace();
}
}
}

程序输出结果如下

1311053135
Time:1473599778476
1311053135 100

方法join()和方法get()虽然都能取得计算后的结果值,但对异常的处理存在区别。使用get()方法执行任务时,当子任务出现异常时,可以在main线程中进行捕获。使用join()方法出现异常时则直接抛出。


Java并发编程核心方法与框架-Fork-Join分治编程(一)的更多相关文章

  1. Java并发编程核心方法与框架-TheadPoolExecutor的使用

    类ThreadPoolExecutor最常使用的构造方法是 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAli ...

  2. Java并发编程核心方法与框架-CountDownLatch的使用

    Java多线程编程中经常会碰到这样一种场景:某个线程需要等待一个或多个线程操作结束(或达到某种状态)才开始执行.比如裁判员需要等待运动员准备好后才发送开始指令,运动员要等裁判员发送开始指令后才开始比赛 ...

  3. Java并发编程核心方法与框架-Semaphore的使用

    Semaphore中文含义是信号.信号系统,这个类的主要作用就是限制线程并发数量.如果不限制线程并发数量,CPU资源很快就会被耗尽,每个线程执行的任务会相当缓慢,因为CPU要把时间片分配给不同的线程对 ...

  4. Java并发编程核心方法与框架-CompletionService的使用

    接口CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离.使用submit()执行任务,使用take取得已完成的任务,并按 ...

  5. Java并发编程核心方法与框架-ScheduledExecutorService的使用

    类SchedukedExecutorService的主要作用是可以将定时任务与线程池功能结合. 使用Callable延迟运行(有返回值) public class MyCallableA implem ...

  6. Java并发编程核心方法与框架-ExecutorService的使用

    在ThreadPoolExecutor中使用ExecutorService中的方法 方法invokeAny()和invokeAll()具有阻塞特性 方法invokeAny()取得第一个完成任务的结果值 ...

  7. Java并发编程核心方法与框架-Future和Callable的使用

    Callable接口与Runnable接口对比的主要优点是Callable接口可以通过Future获取返回值.但是Future接口调用get()方法取得结果时是阻塞的,如果调用Future对象的get ...

  8. Java并发编程核心方法与框架-Executors的使用

    合理利用线程池能够带来三个好处 降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 提高线程的可管理性.线程是稀 ...

  9. Java并发编程核心方法与框架-phaser的使用

    arriveAndAwaitAdvance()方法 arriveAndAwaitAdvance()作用是当前线程已经到达屏障,在此等待一段时间,等条件满足后继续向下一个屏障执行. public cla ...

随机推荐

  1. python-汉诺塔递归实现

    摘录自廖雪峰老师教程下的评论,个人备忘,脑细胞已死光 def move(from,to): #将盘子从from移动到to,动画效果需要脑补 print(from,'->',to) def han ...

  2. 【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2745  Solved: 1694[Submit][Statu ...

  3. 【uoj128】 NOI2015—软件包管理器

    http://uoj.ac/problem/128 (题目链接) 题意 给出一棵树,每个节点代表一个软件包,维护卸载和安装操作.若要卸载节点x,那么必须卸载它的子树上的所有软件包:若要安装节点x必须安 ...

  4. bzoj2683简单题

    #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> ...

  5. QIBO CMS /inc/common.inc.php Local Variables Overriding Vul In $_FILES

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 齐博在/inc/common.inc.php使用$$_key=$value.ext ...

  6. Google Guava vs Apache Commons for Argument Validation

    It is an established good practice to validate method arguments at the beginning of the method body. ...

  7. 和redis谈一场恋爱(第二天约会了解彼此)

    最近使用了Memcache,带来的便利已经让我欣喜若狂.开启了另一种又快又好的方式存储和读取数据.中间经过了一番折腾,学习了mysql,终于有学到了redis. Redis的全名是Remote Dic ...

  8. 浅谈DDOS攻击

    preface 做过网站运维的同事来说,绝对遇到过DDOS的攻击吧,这样的攻击实属令人头疼,那么今年就说DDOS的攻击与防护吧. 原理 DDOS(Distributed Denial Of Servi ...

  9. codeforce B Island Puzzle

    B. Island Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  10. Python 数据处理----对定长数据的处理

    场景: 有时候我们对大量数据进行处理,对性能要求很高,而且数据都是定长的,比如对移动信息登记表进行处理:名字 身份证信息 手机号码 这些都是定长的,今天小花来教大家如何对此类数据进行处理. 步骤一: ...