在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. UML类图中的六种关系及实例【补充】

    ·继承和接口都比较常见,通过继承子类可以直接使用父类的(public,protected属性以及方法:而实现了Speakable接口的Person类必须定义其所有方法,包括speak()): ·依赖指 ...

  2. Leetcode Odd Even Linked List

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  3. 【BZOJ-2962】序列操作 线段树 + 区间卷积

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 678  Solved: 246[Submit][Status][Discuss] ...

  4. BZOJ4721 [Noip2016]蚯蚓

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  5. [NOIP2015] 提高组 洛谷P2668 斗地主

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  6. malware analysis、Sandbox Principles、Design && Implementation

    catalog . 引言 . sandbox introduction . Sandboxie . seccomp(short for secure computing mode): API级沙箱 . ...

  7. java.io.IOException: No FileSystem for scheme: hdfs

    在这篇文章中,介绍了如何将Maven依赖的包一起打包进jar包.使用maven-assembly打成jar后,将这个jar提供给其他工程引用的时候,报出如下错误: log4j:WARN No appe ...

  8. linux系统安装jdk

    OpenJdk8安装: sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get install openj ...

  9. python实现自动输入命令回车操作

    苦逼的在sf上等了一天(问题链接),都没人来解答,只好自己想办法,东平西凑还是勉强实现了,记录一下: 安装完python2.7后,在cmd命令行输入python回车,后出现python相关的提示信息, ...

  10. django1.8 提示(1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dictionary takes precedence. You must put the values of the following settings into your defau

    原因是升级之后不推荐使用单独的 TEMPLATES_DIR这样的设置了,使用TEMPLATE = []这种就好了 详细见https://openedx.atlassian.net/browse/TNL ...