- 浏览: 111744 次
- 性别:
- 来自: 珠海
文章分类
- 全部博客 (83)
- 职场电影20部 (1)
- 成功的关键在于运作 (1)
- 没有耐心去等待成功的到来,只好用一生的耐心去面对失败 (1)
- 穷人最缺少的是什么 (1)
- HTML特殊字符表 (1)
- Java内存泄露的理解与解决 (1)
- 程序员是不是只在乎自己的一亩三分地 (1)
- 细节优化提升资源利用率 (1)
- 用Resin 3.1.2分析系统性能瓶颈 (1)
- 如何才算掌握Java (1)
- oracle 分页sql语句 (1)
- JDK 7 中的 Fork/Join 模式 (1)
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序 (1)
- 观察者模式(Observer Pattern)的例子 (1)
- JAVA IO总结 (1)
- 2011年10月编程语言排行榜:Java人气持续走低 (1)
- 2011年8月编程语言排行榜:F#首次进入前20 (1)
- 前端开发参考资源 (1)
- 装逼犯是怎样练成的--看看你装逼了没有 (1)
- C程序员装逼指南 (1)
- 高级程序员装逼指南 (1)
- 21条精通程序员装逼技术 (1)
- 【程序员必看】你还装逼么?还牛逼呢? (1)
- Java程序员使用Grails的十大优势 (1)
- 我是怎么了,总感被人盯梢 (1)
- JAVA自定义标签 (1)
- JAVA版本问题 bad version number in class file 的解决方法 (1)
- 学习Java必须知道的基本概念 (1)
- java获取windows系统信息(CPU (1)
- 内存 (1)
- 文件系统 (1)
- 硬盘大小) (1)
- Java内存泄露与溢出的区别 (1)
- Java的resultset与.net的dataset 有什么区别? (1)
- java类定时器Timer和TimerTask的使用实例及内部类 (1)
- 了解什么是框架、构件与设计模式 (1)
- lucene2.9 中文分词学习和SmartChineseAnalyzer的用法 (1)
- Java什么是面向对象和面向对象特性 (1)
- Tomcat 7启动异常:java.lang.IllegalArgumentException: taglib definition not consistent with specification version (0)
- Struts2中使用FreeMarker充当表现层 (1)
- 7个改变世界的Java项目 (1)
- jquery中,html、val与text三者属性取值的联系与区别 (1)
- 一个简单的面试题(java) (1)
- Tomcat (1)
- Hibernate的优点 (1)
- Java内存相关的几个配置 (1)
- 进行BPM建设的十大步骤 (1)
- 中欧行-自找的麻烦 (1)
- 去年中国12省公路收费高达1025亿,为何还叫亏? (1)
- 职场中不可深交的五种人 (1)
- 中国IT工作者35岁后的发展出路调查报告(1) (1)
- 中国IT工作者35岁后的发展出路调查报告(2) (1)
- 中国IT工作者35岁后的发展出路调查报告(3) (1)
- 中国IT工作者35岁后的发展出路调查报告(4) (1)
- 架构学习笔记—Amazon (1)
- Windows 8背后数字:支持2种架构7种程序语言 (1)
- 说好的Cache呢 (1)
- 10 000小时的标准----是否有先天的才能 (1)
- java程序员需要练就的孤独九剑 (1)
- 中国程序员的真实写照!悲哀···· (1)
- 如何把Object对象转换为XML (1)
- Java的四种引用 (1)
- java中byte转换int时为何与0xff进行与运算 (1)
- java 写文件时如何正确输入换行字符. (1)
- Java服务框架Dubbo (1)
- 深入分析 Java I/O 的工作机制 (1)
- 推荐十个最好的Java性能故障排除工具 (1)
- 消灭程序员需要百年吗? (1)
- 苹果又损失了一位高管全球安全部门VP John Theriault (1)
- 中央情报局CIA通过Facebook等社交媒体对全球实施网络监视 (1)
- Java 中的finally你知多少? (1)
- Java 7 NIO.2 实现文件系统监视 (1)
- java中的引用到底是传值还是传址? (1)
- 作为程序员,难道我们不应该自豪吗 (1)
最新评论
-
iamstruts2:
CyclicAction在jdk7中被CANCEL掉了
JDK 7 中的 Fork/Join 模式 -
康乐狂花:
了不起
作为程序员,难道我们不应该自豪吗 -
黎明的曙光:
一定是传值!引用类型传的是地址的副本,值类型传的存储单元内容的 ...
java中的引用到底是传值还是传址? -
Berson_Cheng:
前几个根本就是为了你所谓的理论而构造出来的,根本就没什么用。尤 ...
Java 中的finally你知多少? -
ayxtlztds24:
写的真好啊
作为程序员,难道我们不应该自豪吗
随着多核时代的来临,软件开发人员不得不开始关注并行编程领域。而 JDK 7 中将会加入的 Fork/Join 模式是处理并行编程的一个经典的方法。虽然不能解决所有的问题,但是在它的适用范围之内,能够轻松的利用多个 CPU 提供的计算资源来协作完成一个复杂的计算任务。通过利用 Fork/Join 模式,我们能够更加顺畅的过渡到多核的时代。本文将介绍使用 JDK 7 中 Fork/Join 模式的方法和其他相关改进。阅读本文之后,读者将能够独立地在软件开发中使用 Fork/Join 模式来改进程序的性能。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
随 着多核芯片逐渐成为主流,大多数软件开发人员不可避免地需要了解并行编程的知识。而同时,主流程序语言正在将越来越多的并行特性合并到标准库或者语言本身 之中。我们可以看到,JDK 在这方面同样走在潮流的前方。在 JDK 标准版 5 中,由 Doug Lea 提供的并行框架成为了标准库的一部分(JSR-166)。随后,在 JDK 6 中,一些新的并行特性,例如并行 collection 框架,合并到了标准库中(JSR-166x)。直到今天,尽管 Java SE 7 还没有正式发布,一些并行相关的新特性已经出现在 JSR-166y 中:
- Fork/Join 模式;
- TransferQueue,它继承自 BlockingQueue 并能在队列满时阻塞“生产者”;
- ArrayTasks/ListTasks,用于并行执行某些数组/列表相关任务的类;
- IntTasks/LongTasks/DoubleTasks,用于并行处理数字类型数组的工具类,提供了排序、查找、求和、求最小值、求最大值等功能;
其 中,对 Fork/Join 模式的支持可能是对开发并行软件来说最通用的新特性。在 JSR-166y 中,Doug Lea 实现 ArrayTasks/ListTasks/IntTasks/LongTasks/DoubleTasks 时就大量的用到了 Fork/Join 模式。读者还需要注意一点,因为 JDK 7 还没有正式发布,因此本文涉及到的功能和发布版本有可能不一样。
Fork/Join 模式有自己的适用范围。如果一个应用能被分解成多个子任务,并且组合多个子任务的结果就能够获得最终的答案,那么这个应用就适合用 Fork/Join 模式来解决。图 1 给出了一个 Fork/Join 模式的示意图,位于图上部的 Task 依赖于位于其下的 Task 的执行,只有当所有的子任务都完成之后,调用者才能获得 Task 0 的返回结果。
可 以说,Fork/Join 模式能够解决很多种类的并行问题。通过使用 Doug Lea 提供的 Fork/Join 框架,软件开发人员只需要关注任务的划分和中间结果的组合就能充分利用并行平台的优良性能。其他和并行相关的诸多难于处理的问题,例如负载平衡、同步等, 都可以由框架采用统一的方式解决。这样,我们就能够轻松地获得并行的好处而避免了并行编程的困难且容易出错的缺点。
在开始尝试 Fork/Join 模式之前,我们需要从 Doug Lea 主持的 Concurrency JSR-166 Interest Site 上下载 JSR-166y 的源代码,并且我们还需要安装最新版本的 JDK 6(下载网址请参阅 参考资源 )。Fork/Join 模式的使用方式非常直观。首先,我们需要编写一个 ForkJoinTask 来完成子任务的分割、中间结果的合并等工作。随后,我们将这个 ForkJoinTask 交给 ForkJoinPool 来完成应用的执行。
通
常我们并不直接继承 ForkJoinTask,它包含了太多的抽象方法。针对特定的问题,我们可以选择 ForkJoinTask
的不同子类来完成任务。RecursiveAction 是 ForkJoinTask 的一个子类,它代表了一类最简单的
ForkJoinTask:不需要返回值,当子任务都执行完毕之后,不需要进行中间结果的组合。如果我们从 RecursiveAction
开始继承,那么我们只需要重载 protected void compute()
方法。下面,我们来看看怎么为快速排序算法建立一个 ForkJoinTask 的子类:
class SortTask extends RecursiveAction { final long[] array; final int lo; final int hi; private int THRESHOLD = 30; public SortTask(long[] array) { this.array = array; this.lo = 0; this.hi = array.length - 1; } public SortTask(long[] array, int lo, int hi) { this.array = array; this.lo = lo; this.hi = hi; } protected void compute() { if (hi - lo < THRESHOLD) sequentiallySort(array, lo, hi); else { int pivot = partition(array, lo, hi); coInvoke(new SortTask(array, lo, pivot - 1), new SortTask(array, pivot + 1, hi)); } } private int partition(long[] array, int lo, int hi) { long x = array[hi]; int i = lo - 1; for (int j = lo; j < hi; j++) { if (array[j] <= x) { i++; swap(array, i, j); } } swap(array, i + 1, hi); return i + 1; } private void swap(long[] array, int i, int j) { if (i != j) { long temp = array[i]; array[i] = array[j]; array[j] = temp; } } private void sequentiallySort(long[] array, int lo, int hi) { Arrays.sort(array, lo, hi + 1); } } |
在 清单 1
中,SortTask 首先通过 partition()
方法将数组分成两个部分。随后,两个子任务将被生成并分别排序数组的两个部分。当子任务足够小时,再将其分割为更小的任务反而引起性能的降低。因此,这里我们使用一个 THRESHOLD
,限定在子任务规模较小时,使用直接排序,而不是再将其分割成为更小的任务。其中,我们用到了 RecursiveAction 提供的方法 coInvoke()
。它表示:启动所有的任务,并在所有任务都正常结束后返回。如果其中一个任务出现异常,则其它所有的任务都取消。coInvoke()
的参数还可以是任务的数组。
现在剩下的工作就是将 SortTask 提交到 ForkJoinPool 了。ForkJoinPool()
默认建立具有与 CPU 可使用线程数相等线程个数的线程池。我们在一个 JUnit 的 test
方法中将 SortTask 提交给一个新建的 ForkJoinPool:
@Test public void testSort() throws Exception { ForkJoinTask sort = new SortTask(array); ForkJoinPool fjpool = new ForkJoinPool(); fjpool.submit(sort); fjpool.shutdown(); fjpool.awaitTermination(30, TimeUnit.SECONDS); assertTrue(checkSorted(array)); } |
在上面的代码中,我们用到了 ForkJoinPool 提供的如下函数:
-
submit()
:将 ForkJoinTask 类的对象提交给 ForkJoinPool,ForkJoinPool 将立刻开始执行 ForkJoinTask。 -
shutdown()
:执行此方法之后,ForkJoinPool 不再接受新的任务,但是已经提交的任务可以继续执行。如果希望立刻停止所有的任务,可以尝试shutdownNow()
方法。 -
awaitTermination()
:阻塞当前线程直到 ForkJoinPool 中所有的任务都执行结束。
并行快速排序的完整代码如下所示:
package tests; import static org.junit.Assert.*; import java.util.Arrays; import java.util.Random; import java.util.concurrent.TimeUnit; import jsr166y.forkjoin.ForkJoinPool; import jsr166y.forkjoin.ForkJoinTask; import jsr166y.forkjoin.RecursiveAction; import org.junit.Before; import org.junit.Test; class SortTask extends RecursiveAction { final long[] array; final int lo; final int hi; private int THRESHOLD = 0; //For demo only public SortTask(long[] array) { this.array = array; this.lo = 0; this.hi = array.length - 1; } public SortTask(long[] array, int lo, int hi) { this.array = array; this.lo = lo; this.hi = hi; } protected void compute() { if (hi - lo < THRESHOLD) sequentiallySort(array, lo, hi); else { int pivot = partition(array, lo, hi); System.out.println("\npivot = " + pivot + ", low = " + lo + ", high = " + hi); System.out.println("array" + Arrays.toString(array)); coInvoke(new SortTask(array, lo, pivot - 1), new SortTask(array, pivot + 1, hi)); } } private int partition(long[] array, int lo, int hi) { long x = array[hi]; int i = lo - 1; for (int j = lo; j < hi; j++) { if (array[j] <= x) { i++; swap(array, i, j); } } swap(array, i + 1, hi); return i + 1; } private void swap(long[] array, int i, int j) { if (i != j) { long temp = array[i]; array[i] = array[j]; array[j] = temp; } } private void sequentiallySort(long[] array, int lo, int hi) { Arrays.sort(array, lo, hi + 1); } } public class TestForkJoinSimple { private static final int NARRAY = 16; //For demo only long[] array = new long[NARRAY]; Random rand = new Random(); @Before public void setUp() { for (int i = 0; i < array.length; i++) { array[i] = rand.nextLong()%100; //For demo only } System.out.println("Initial Array: " + Arrays.toString(array)); } @Test public void testSort() throws Exception { ForkJoinTask sort = new SortTask(array); ForkJoinPool fjpool = new ForkJoinPool(); fjpool.submit(sort); fjpool.shutdown(); fjpool.awaitTermination(30, TimeUnit.SECONDS); assertTrue(checkSorted(array)); } boolean checkSorted(long[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > (a[i + 1])) { return false; } } return true; } } |
运行以上代码,我们可以得到以下结果:
Initial Array: [46, -12, 74, -67, 76, -13, -91, -96] pivot = 0, low = 0, high = 7 array[-96, -12, 74, -67, 76, -13, -91, 46] pivot = 5, low = 1, high = 7 array[-96, -12, -67, -13, -91, 46, 76, 74] pivot = 1, low = 1, high = 4 array[-96, -91, -67, -13, -12, 46, 74, 76] pivot = 4, low = 2, high = 4 array[-96, -91, -67, -13, -12, 46, 74, 76] pivot = 3, low = 2, high = 3 array[-96, -91, -67, -13, -12, 46, 74, 76] pivot = 2, low = 2, high = 2 array[-96, -91, -67, -13, -12, 46, 74, 76] pivot = 6, low = 6, high = 7 array[-96, -91, -67, -13, -12, 46, 74, 76] pivot = 7, low = 7, high = 7 array[-96, -91, -67, -13, -12, 46, 74, 76] |
|
除了 RecursiveAction,Fork/Join 框架还提供了其他 ForkJoinTask 子类:带有返回值的 RecursiveTask,使用 finish()
方法显式中止的 AsyncAction 和 LinkedAsyncAction,以及可使用 TaskBarrier 为每个任务设置不同中止条件的 CyclicAction。
从 RecursiveTask 继承的子类同样需要重载 protected void compute()
方法。与 RecursiveAction 稍有不同的是,它可使用泛型指定一个返回值的类型。下面,我们来看看如何使用 RecursiveTask 的子类。
class Fibonacci extends RecursiveTask<Integer> { final int n; Fibonacci(int n) { this.n = n; } private int compute(int small) { final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; return results[small]; } public Integer compute() { if (n <= 10) { return compute(n); } Fibonacci f1 = new Fibonacci(n - 1); Fibonacci f2 = new Fibonacci(n - 2); f1.fork(); f2.fork(); return f1.join() + f2.join(); } } |
在 清单 4
中, Fibonacci 的返回值为 Integer 类型。其 compute()
函数首先建立两个子任务,启动子任务执行,阻塞以等待子任务的结果返回,相加后得到最终结果。同样,当子任务足够小时,通过查表得到其结果,以减小因过多地分割任务引起的性能降低。其中,我们用到了 RecursiveTask 提供的方法 fork()
和 join()
。它们分别表示:子任务的异步执行和阻塞等待结果完成。
现在剩下的工作就是将 Fibonacci 提交到 ForkJoinPool 了,我们在一个 JUnit 的 test
方法中作了如下处理:
清单 5. 将 Fibonacci 提交到 ForkJoinPool
@Test public void testFibonacci() throws InterruptedException, ExecutionException { ForkJoinTask<Integer> fjt = new Fibonacci(45); ForkJoinPool fjpool = new ForkJoinPool(); Future<Integer> result = fjpool.submit(fjt); // do something System.out.println(result.get()); } |
CyclicAction 的用法稍微复杂一些。如果一个复杂任务需要几个线程协作完成,并且线程之间需要在某个点等待所有其他线程到达,那么我们就能方便的用 CyclicAction 和 TaskBarrier 来完成。图 2 描述了使用 CyclicAction 和 TaskBarrier 的一个典型场景。
图 2. 使用 CyclicAction 和 TaskBarrier 执行多线程任务
继承自 CyclicAction 的子类需要 TaskBarrier 为每个任务设置不同的中止条件。从 CyclicAction 继承的子类需要重载 protected void compute()
方法,定义在 barrier
的每个步骤需要执行的动作。compute()
方法将被反复执行直到 barrier
的 isTerminated()
方法返回 True
。TaskBarrier 的行为类似于 CyclicBarrier。下面,我们来看看如何使用 CyclicAction 的子类。
class ConcurrentPrint extends RecursiveAction { protected void compute() { TaskBarrier b = new TaskBarrier() { protected boolean terminate(int cycle, int registeredParties) { System.out.println("Cycle is " + cycle + ";" + registeredParties + " parties"); return cycle >= 10; } }; int n = 3; CyclicAction[] actions = new CyclicAction[n]; for (int i = 0; i < n; ++i) { final int index = i; actions[i] = new CyclicAction(b) { protected void compute() { System.out.println("I'm working " + getCycle() + " " + index); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }; } for (int i = 0; i < n; ++i) actions[i].fork(); for (int i = 0; i < n; ++i) actions[i].join(); } } |
在 清单 6
中,CyclicAction[]
数组建立了三个任务,打印各自的工作次数和序号。而在 b.terminate()
方法中,我们设置的中止条件表示重复 10 次计算后中止。现在剩下的工作就是将 ConcurrentPrint 提交到 ForkJoinPool 了。我们可以在 ForkJoinPool 的构造函数中指定需要的线程数目,例如 ForkJoinPool(4)
就表明线程池包含 4 个线程。我们在一个 JUnit 的 test
方法中运行 ConcurrentPrint 的这个循环任务:
@Test public void testBarrier () throws InterruptedException, ExecutionException { ForkJoinTask fjt = new ConcurrentPrint(); ForkJoinPool fjpool = new ForkJoinPool(4); fjpool.submit(fjt); fjpool.shutdown(); } |
RecursiveTask 和 CyclicAction 两个例子的完整代码如下所示:
清单 8. RecursiveTask 和 CyclicAction 两个例子的完整代码
package tests; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import jsr166y.forkjoin.CyclicAction; import jsr166y.forkjoin.ForkJoinPool; import jsr166y.forkjoin.ForkJoinTask; import jsr166y.forkjoin.RecursiveAction; import jsr166y.forkjoin.RecursiveTask; import jsr166y.forkjoin.TaskBarrier; import org.junit.Test; class Fibonacci extends RecursiveTask<Integer> { final int n; Fibonacci(int n) { this.n = n; } private int compute(int small) { final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; return results[small]; } public Integer compute() { if (n <= 10) { return compute(n); } Fibonacci f1 = new Fibonacci(n - 1); Fibonacci f2 = new Fibonacci(n - 2); System.out.println("fork new thread for " + (n - 1)); f1.fork(); System.out.println("fork new thread for " + (n - 2)); f2.fork(); return f1.join() + f2.join(); } } class ConcurrentPrint extends RecursiveAction { protected void compute() { TaskBarrier b = new TaskBarrier() { protected boolean terminate(int cycle, int registeredParties) { System.out.println("Cycle is " + cycle + ";" + registeredParties + " parties"); return cycle >= 10; } }; int n = 3; CyclicAction[] actions = new CyclicAction[n]; for (int i = 0; i < n; ++i) { final int index = i; actions[i] = new CyclicAction(b) { protected void compute() { System.out.println("I'm working " + getCycle() + " " + index); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }; } for (int i = 0; i < n; ++i) actions[i].fork(); for (int i = 0; i < n; ++i) actions[i].join(); } } public class TestForkJoin { @Test public void testBarrier () throws InterruptedException, ExecutionException { System.out.println("\ntesting Task Barrier ..."); ForkJoinTask fjt = new ConcurrentPrint(); ForkJoinPool fjpool = new ForkJoinPool(4); fjpool.submit(fjt); fjpool.shutdown(); } @Test public void testFibonacci () throws InterruptedException, ExecutionException { System.out.println("\ntesting Fibonacci ..."); final int num = 14; //For demo only ForkJoinTask<Integer> fjt = new Fibonacci(num); ForkJoinPool fjpool = new ForkJoinPool(); Future<Integer> result = fjpool.submit(fjt); // do something System.out.println("Fibonacci(" + num + ") = " + result.get()); } } |
运行以上代码,我们可以得到以下结果:
testing Task Barrier ... I'm working 0 2 I'm working 0 0 I'm working 0 1 Cycle is 0; 3 parties I'm working 1 2 I'm working 1 0 I'm working 1 1 Cycle is 1; 3 parties I'm working 2 0 I'm working 2 1 I'm working 2 2 Cycle is 2; 3 parties I'm working 3 0 I'm working 3 2 I'm working 3 1 Cycle is 3; 3 parties I'm working 4 2 I'm working 4 0 I'm working 4 1 Cycle is 4; 3 parties I'm working 5 1 I'm working 5 0 I'm working 5 2 Cycle is 5; 3 parties I'm working 6 0 I'm working 6 2 I'm working 6 1 Cycle is 6; 3 parties I'm working 7 2 I'm working 7 0 I'm working 7 1 Cycle is 7; 3 parties I'm working 8 1 I'm working 8 0 I'm working 8 2 Cycle is 8; 3 parties I'm working 9 0 I'm working 9 2 testing Fibonacci ... fork new thread for 13 fork new thread for 12 fork new thread for 11 fork new thread for 10 fork new thread for 12 fork new thread for 11 fork new thread for 10 fork new thread for 9 fork new thread for 10 fork new thread for 9 fork new thread for 11 fork new thread for 10 fork new thread for 10 fork new thread for 9 Fibonacci(14) = 610 |
|
从 以上的例子中可以看到,通过使用 Fork/Join 模式,软件开发人员能够方便地利用多核平台的计算能力。尽管还没有做到对软件开发人员完全透明,Fork/Join 模式已经极大地简化了编写并发程序的琐碎工作。对于符合 Fork/Join 模式的应用,软件开发人员不再需要处理各种并行相关事务,例如同步、通信等,以难以调试而闻名的死锁和 data race 等错误也就不会出现,提升了思考问题的层次。你可以把 Fork/Join 模式看作并行版本的 Divide and Conquer 策略,仅仅关注如何划分任务和组合中间结果,将剩下的事情丢给 Fork/Join 框架。
在实际工作中利用 Fork/Join 模式,可以充分享受多核平台为应用带来的免费午餐。
学习
- 阅读文章“The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software ”:了解为什么从现在开始每个严肃的软件工作者都应该了解并行编程方法。
- 阅读 Doug Lea 的文章“A Java Fork/Join Framework ”:了解 Fork/Join 模式的实现机制和执行性能。
- 阅读 developerWorks 文章“驯服 Tiger:并发集合 ”:了解如何使用并行 Collection 库。
- 阅读 developerWorks 文章“Java 理论与实践:非阻塞算法简介 ”:介绍了 JDK 5 在并行方面的重要增强以及在 JDK5 平台上如何实现非阻塞算法的一般介绍。
- 书籍“Java Concurrency in Practice ”:介绍了大量的并行编程技巧、反模式、可行的解决方案等,它对于 JDK 5 中的新特性也有详尽的介绍。
相关推荐
JDK 7 中引入的 Fork/Join 模式是一种基于分治策略的并行编程模型,旨在简化在多核处理器环境下实现高效的并行计算。这一模式的核心思想是将复杂的大任务拆分成一系列小任务,然后将这些小任务并行执行,最后再合并...
Fork/Join框架是Java7引入的一种用于并行任务执行的框架,它允许将复杂任务拆分成多个子任务,并行执行,然后通过join操作将结果聚合。Fork/Join框架特别适合处理可以递归拆分的计算密集型任务,比如大数据集的搜索...
新特性主要涉及:对于JDK7中Fork/Join并行处理的升级;支持Lambda表达式;添加了Stream API;对于注解的拓展,加入了类型注解、重复注解;在G1回收器中支持字符串去重;内存空间中删除了永久代,引入了元空间。
在Java编程中,线程池和并发任务执行是常见的方式,但在某些场景下,我们可以利用JDK的ForkJoin框架来构建更加高效和易用的并发组件。ForkJoin框架自Java 7引入,它为处理大型任务提供了一种分解成多个子任务并行...
2. **多路归并排序(Fork/Join Framework)**:这是一个并行计算框架,用于将大型任务拆分为更小的子任务,以利用多核处理器的并行处理能力。 3. **字符串inswitch语句**:在switch语句中可以直接使用字符串,提高...
` 这样的写法在JDK7中成为可能。 JDK7还增强了异常处理,引入了“异常链”功能,允许一个异常捕获另一个异常,并将它们串联起来,便于追踪错误来源。此外,新的“catch多个异常”语法使得在一个catch块中处理多种...
而在JDK7中,实现了自动关闭资源的机制,只要资源实现了`java.lang.AutoCloseable`接口,就可以在try块中直接声明并使用,程序结束时会自动调用`close()`方法。 其次,多线程处理方面,JDK7引入了Fork/Join框架,它...
6. **Fork/Join框架(Fork/Join Framework)**:用于并行计算的新框架,基于工作窃取算法。 7. **新的Swing事件模型**:改进了Swing GUI库的事件处理机制。 8. **改进的JSON支持**:提供了一个新的`javax.json`包来...
例如,动态语言支持、Fork/Join框架、并发工具的增强以及新的编译器——CTW(Compartment Type-Wise)等。这些更新显著提高了开发效率和程序性能。 针对Aarch64(也称为ARM64或AArch64)架构,这是一种64位指令集...
JDK7引入了许多新特性,例如动态类型语言支持( invokedynamic 指令)、Project Coin的小改进(如 try-with-resources 语句、多 catch 块、改进的类型推断等),以及并发改进(如Fork/Join框架和Parallel Scanning)...
在JDK 7中,垃圾回收机制得到了显著的优化。特别是对G1(Garbage First)收集器进行了增强,使得它在多核处理器上表现更佳,减少了应用程序的暂停时间,提高了吞吐量。 ##### 2.2 文件系统API增强 为了更好地支持...
5. **JDK7新特性<五> fork/join 框架** Fork/Join框架是Java并行编程的一个重要工具,它基于分治策略,允许开发者将大任务拆分成小任务,然后并行执行,最后合并结果,显著提高了处理大规模计算任务的能力。 6. **...
6. ** 并发改进**:JDK 8在并发编程方面也做了改进,例如`Fork/Join`框架的改进,以及`ConcurrentHashMap`性能的提升。 7. ** Nashorn JavaScript引擎**:JDK 8引入了一个名为Nashorn的JavaScript引擎,允许Java...
在Java 7中,有几个关键的特性值得注意: 1. **多线程并发控制**:引入了Fork/Join框架,通过工作窃取算法提高并行计算效率,同时提供了`Phaser`、`CountDownLatch` 和 `CyclicBarrier` 等并发工具类。 2. **...
在JDK1.8中,有许多重要的更新和改进,其中最为人所知的可能就是Lambda表达式和Stream API的引入,它们极大地提升了Java语言的函数式编程能力。Lambda表达式使得匿名函数的编写更为简洁,可以更方便地处理回调和事件...
3. **多线程改进**:JDK 7提供了`Fork/Join`框架,这是一种基于工作窃取算法的并行编程模型,用于高效地执行大量可分解的任务。 4. **try-with-resources语句**:这个新特性允许自动关闭实现了`AutoCloseable`接口...
"JDK7" 是JDK的一个重要版本,引入了多个新特性,如动态类型语言支持、Fork/Join框架、try-with-resources语句等。 "Linux" 是一种开源的操作系统,广泛应用于服务器、桌面环境和其他嵌入式设备。 **详细知识点:**...
【标签】"jdk7"指代了Java平台的第七个主要版本,它在2011年发布,引入了许多新的特性,如try-with-resources语句、多线程的Fork/Join框架、改进的类型推断(Project Coin)、文件系统API(NIO.2)以及并发工具的...
在Java 7中,通过类型推断,我们可以更简洁地创建泛型实例,省略new表达式后的类型参数。例如: ```java List<String> list = new ArrayList(); // 可以简化为 List<String> list = new ArrayList(); ``` #### 4. ...
JDK1.7新特性介绍 1. 对Java集合(Collections)的增强支持 2. 在Switch中可用String 在JDK7 的正式版本中,你可以在switch的表达式中用String类型 ...9. 增加了fork/join框架来增强对处理多核并行计算的支持