标签 ‘ join

Java Fork/Join框架

原文链接:A Java Fork/Join Framework(PDF) – Doug Lea

译序

Doug Lea 大神关于Java 7引入的他写的Fork/Join框架的论文。

响应式编程Reactive Programming / RP)作为一种范式在整个业界正在逐步受到认可和落地,是对过往系统的业务需求理解梳理之后对系统技术设计/架构模式的提升总结。Java作为一个成熟平台,对于趋势一向有些稳健的接纳和跟进能力,有着令人惊叹的生命活力:

  1. Java 7提供了ForkJoinPool,支持了Java 8提供的Stream
  2. 另外Java 8还提供了Lamda(有效地表达和使用RP需要FP的语言构件和理念)。
  3. 有了前面的这些稳健但不失时机的准备,在Java 9中提供了面向RP的官方Flow API,实际上是直接把Reactive Streams的接口加在Java标准库中,即Reactive Streams规范转正了,Reactive StreamsRP的基础核心组件。Flow API标志着RP由集市式的自由探索阶段 向 教堂式的统一使用的转变。

通过上面这些说明,可以看到ForkJoinPool的基础重要性。

对了,另外提一下Java 9Flow API@author也是 Doug Lee 哦~

PS:基于Alex/萧欢 翻译、方腾飞 校对的译文稿:Java Fork Join 框架,补译『结论』之后3节,调整了格式和一些用词,整理成完整的译文。译文源码在GitHub的这个仓库中,可以提交Issue/Fork后提交代码来建议/指正。

0. 摘要

这篇论文描述了Fork/Join框架的设计、实现以及性能,这个框架通过(递归的)把问题划分为子任务,然后并行的执行这些子任务,等所有的子任务都结束的时候,再合并最终结果的这种方式来支持并行计算编程。总体的设计参考了为Cilk设计的work-stealing框架。就设计层面来说主要是围绕如何高效的去构建和管理任务队列以及工作线程来展开的。性能测试的数据显示良好的并行计算程序将会提升大部分应用,同时也暗示了一些潜在的可以提升的空间。

阅读全文

Fork/Join框架(六)取消任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

取消任务

当你在一个ForkJoinPool类中执行ForkJoinTask对象,在它们开始执行之前,你可以取消执行它们。ForkJoinTask类提供cancel()方法用于这个目的。当你想要取消一个任务时,有一些点你必须考虑一下,这些点如下:

  • ForkJoinPool类并没有提供任何方法来取消正在池中运行或等待的所有任务。
  • 当你取消一个任务时,你不能取消一个已经执行的任务。

在这个指南中,你将实现取消ForkJoinTask对象的例子。你将查找数在数组中的位置。第一个找到这个数的任务将取消剩下的任务(未找到这个数的任务)。由于Fork/Join框架并没有提供这种功能,所以,你将实现一个辅助类来做这个取消功能。
阅读全文

Fork/Join框架(五)在任务中抛出异常

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

在任务中抛出异常

在Java中有两种异常:

  • 已检查异常(Checked exceptions):这些异常必须在一个方法的throws从句中指定或在内部捕捉它们。比如:IOException或ClassNotFoundException。
  • 未检查异常(Unchecked exceptions):这些异常不必指定或捕捉。比如:NumberFormatException。

在ForkJoinTask类的compute()方法中,你不能抛出任何已检查异常,因为在这个方法的实现中,它没有包含任何抛出(异常)声明。你必须包含必要的代码来处理异常。但是,你可以抛出(或者它可以被任何方法或使用内部方法的对象抛出)一个未检查异常。ForkJoinTask和ForkJoinPool类的行为与你可能的期望不同。程序不会结束执行,并且你将不会在控制台看到任何关于异常的信息。它只是被吞没,好像它没抛出(异常)。你可以使用ForkJoinTask类的一些方法,得知一个任务是否抛出异常及其异常种类。在这个指南中,你将学习如何获取这些信息。 阅读全文

Fork/Join框架(四)异步运行任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

异步运行任务

当你在ForkJoinPool中执行ForkJoinTask时,你可以使用同步或异步方式来实现。当你使用同步方式时,提交任务给池的方法直到提交的任务完成它的执行,才会返回结果。当你使用异步方式时,提交任务给执行者的方法将立即返回,所以这个任务可以继续执行。

你应该意识到这两个方法有很大的区别,当你使用同步方法,调用这些方法(比如:invokeAll()方法)的任务将被阻塞,直到提交给池的任务完成它的执行。这允许ForkJoinPool类使用work-stealing算法,分配一个新的任务给正在执行睡眠任务的工作线程。反之,当你使用异步方法(比如:fork()方法),这个任务将继续它的执行,所以ForkJoinPool类不能使用work-stealing算法来提高应用程序的性能。在这种情况下,只有当你调用join()或get()方法来等待任务的完成时,ForkJoinPool才能使用work-stealing算法。 阅读全文

Java Fork Join 框架(四)性能

原文 http://gee.cs.oswego.edu/dl/papers/fj.pdf   作者:Doug Lea   译者:萧欢

4性能

如今,随着编译器与Java虚拟机性能的不断提升,性能测试结果也仅仅只能适用一时。但是,本节中所提到的测试结果数据却能揭示Fork/join框架的基本特性。

下面表格中简单介绍了在下文将会用到的一组fork/join测试程序。这些程序是从util.concurrent包里的示例代码改编而来,用来展示fork/join框架在解决不同类型的问题模型时所表现的差异,同时得到该框架在一些常见的并行测试程序上的测试结果。

阅读全文

Fork/Join框架(三)加入任务的结果

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

加入任务的结果

Fork/Join框架提供了执行返回一个结果的任务的能力。这些任务的类型是实现了RecursiveTask类。这个类继承了ForkJoinTask类和实现了执行者框架提供的Future接口。

在任务中,你必须使用Java API方法推荐的结构: 阅读全文

Fork/Join框架(二)创建一个Fork/Join池

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

创建一个Fork/Join池

在这个指南中,你将学习如何使用Fork/Join框架的基本元素。它包括:

  • 创建一个ForkJoinPool对象来执行任务。
  • 创建一个ForkJoinPool执行的ForkJoinTask类。

你将在这个示例中使用Fork/Join框架的主要特点,如下:

  • 你将使用默认构造器创建ForkJoinPool。
  • 在这个任务中,你将使用Java API文档推荐的结构: 阅读全文

Fork/Join框架(一)引言

声明:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

在这个章节中,我们将覆盖:

引言

通常,当你实现一个简单的并发应用程序,你实现一些Runnable对象和相应的 Thread对象。在你的程序中,你控制这些线程的创建、执行和状态。Java 5引入了Executor和ExecutorService接口及其实现类进行了改进(比如:ThreadPoolExecutor类)。 阅读全文

Java Fork Join 框架(三)实现

原文 http://gee.cs.oswego.edu/dl/papers/fj.pdf

作者:Doug Lea  译者Alex  校对:方腾飞

这个框架是由大约800行纯Java代码组成,主要的类是FJTaskRunner,它是java.lang.Thread的子类。FJTasks 自己仅仅维持一个关于结束状态的布尔值,所有其他的操作都是通过当前的工作线程来代理完成的。JFTaskRunnerGroup类用于创建工作线程,维护一些共享的状态(例如:所有工作线程的标示符,在偷取操作时需要),同时还要协调启动和关闭。

更多实现的细节文档可以在util.concurrent并发包中查看。这一节只着重讨论两类问题以及在实现这个框架的时候所形成的一些解决方案:支持高效的双端列表操作(push, pop 和 take), 并且当工作线程在尝试获取新的任务时维持偷取的协议。 阅读全文

Java Fork Join框架 (三) 设计

原文 http://gee.cs.oswego.edu/dl/papers/fj.pdf

作者:Doug Lea
译者:Alex

Fork/Join程序可以在任何支持以下特性的框架之上运行:框架能够让构建的子任务并行执行,并且拥有一种等待子任务运行结束的机制。然而,java.lang.Thread类(同时也包括POSIX pthreads, 这些也是Java线程所基于的基础)对Fork/Join程序来说并不是最优的选择:

  • Fork/Join 任务对同步和管理有简单的和常规的需求。相对于常规的线程来说,fork/join任务所展示的计算布局将会带来更加灵活的调度策略。例如,fork/join任务除了等待子任务外,其他情况下是不需要阻塞的。因此传统的用于跟踪记录阻塞线程的代价在这种情况下实际上是一种浪费。
  • 对于一个合理的基础任务粒度来说,构建和管理一个线程的代价甚至可以比任务执行本身所花费的代价更大。尽管粒度是应该随着应用程序在不同特定平台上运行而做出相应调整的。但是超过线程开销的极端粗粒度会限制并行的发挥。

简而言之,Java标准的线程框架对fork/join程序而言太笨重了。但是既然线程构成了很多其他的并发和并行编程的基础,完全消除这种代价或者为了这种方式而调整线程调度是不可能(或者说不切实际的)。

阅读全文

Java Fork Join框架 (二) 简介

原文 http://gee.cs.oswego.edu/dl/papers/fj.pdf

作者:Doug Lea
译者:Alex

Fork/Join并行方式是获取良好的并行计算性能的一种最简单同时也是最有效的设计技术。Fork/Join并行算法是我们所熟悉的分治算法的并行版本,典型的用法如下:

[code lang=”java”]Result solve(Problem problem) {
if (problem is small)
directly solve problem
else {
split problem into independent parts
fork new subtasks to solve each part
join all subtasks
compose result from subresults
}
}[/code]

Fork操作将会启动一个新的并行fork/join子任务。Join操作会一直等待直到所有的子任务都结束。Fork/Join算法,如同其他分治算法一样,总是会递归的、反复的划分子任务,直到这些子任务可以用足够简单的、短小的顺序方法来执行。

一些相关的编程技术和实例在Java并发编程——设计原则与模式 第二版 [7] 4.4章节中已经讨论过。这篇论文将讨论FJTask的设计(第2节)、实现(第3节)以及性能(第4节),它是一个支持并行编程方式的Java框架。FJTask 作为util.concurrent软件包的一部分,目前可以在http://gee.cs.oswego.edu.获取到。

Java Fork Join 框架

原文地址 作者:Doug Lea  译者:Alex

1. 摘要
2. 简介
3. 设计
4. 实现
5. 性能
6. 结论
7. 致谢
8. 参考文献

return top