The fork/join framework is an implementation of the ExecutorService interface that helps you take advantage of multiple processors. It is designed for work that can be broken into smaller pieces recursively. The goal is to use all the available processing power to enhance the performance of your application.

简单翻一下主题思想:fork/join框架是ExecutorService接口的一个实现,它的目的是解决线程的派生问题。这个框架的本质是将一个任务分解成多个子任务,每个子任务用单独的线程去处理。这里用到了递归的思想。

As with any ExecutorService implementation, the fork/join framework distributes tasks to worker threads in a thread pool. The fork/join framework is distinct because it uses a work-stealing algorithm. Worker threads that run out of things to do can steal tasks from other threads that are still busy.

The center of the fork/join framework is the ForkJoinPool class, an extension of the AbstractExecutorService class. ForkJoinPool implements the core work-stealing algorithm and can execute ForkJoinTask processes.

Basic Use

The first step for using the fork/join framework is to write code that performs a segment of the work. Your code should look similar to the following pseudocode:

if (my portion of the work is small enough)
do the work directly
else
split my work into two pieces
invoke the two pieces and wait for the results

Wrap this code in a ForkJoinTask subclass, typically using one of its more specialized types, either RecursiveTask (which can return a result) or RecursiveAction.

After your ForkJoinTask subclass is ready, create the object that represents all the work to be done and pass it to the invoke() method of a ForkJoinPool instance.

Blurring for Clarity

To help you understand how the fork/join framework works, consider the following example. Suppose that you want to blur an image. The original source image is represented by an array of integers, where each integer contains the color values for a single pixel. The blurred destination image is also represented by an integer array with the same size as the source.

Performing the blur is accomplished by working through the source array one pixel at a time. Each pixel is averaged with its surrounding pixels (the red, green, and blue components are averaged), and the result is placed in the destination array. Since an image is a large array, this process can take a long time. You can take advantage of concurrent processing on multiprocessor systems by implementing the algorithm using the fork/join framework. Here is one possible implementation:

public class ForkBlur extends RecursiveAction {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination; // Processing window size; should be odd.
private int mBlurWidth = 15; public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
} protected void computeDirectly() {
int sidePixels = (mBlurWidth - 1) / 2;
for (int index = mStart; index < mStart + mLength; index++) {
// Calculate average.
float rt = 0, gt = 0, bt = 0;
for (int mi = -sidePixels; mi <= sidePixels; mi++) {
int mindex = Math.min(Math.max(mi + index, 0),
mSource.length - 1);
int pixel = mSource[mindex];
rt += (float)((pixel & 0x00ff0000) >> 16)
/ mBlurWidth;
gt += (float)((pixel & 0x0000ff00) >> 8)
/ mBlurWidth;
bt += (float)((pixel & 0x000000ff) >> 0)
/ mBlurWidth;
} // Reassemble destination pixel.
int dpixel = (0xff000000 ) |
(((int)rt) << 16) |
(((int)gt) << 8) |
(((int)bt) << 0);
mDestination[index] = dpixel;
}
} ...

Now you implement the abstract compute() method, which either performs the blur directly or splits it into two smaller tasks. A simple array length threshold helps determine whether the work is performed or split.

protected static int sThreshold = 100000;

protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
} int split = mLength / 2; invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}

If the previous methods are in a subclass of the RecursiveAction class, then setting up the task to run in a ForkJoinPool is straightforward, and involves the following steps:

  1. Create a task that represents all of the work to be done.

    // source image pixels are in src
    // destination image pixels are in dst
    ForkBlur fb = new ForkBlur(src, 0, src.length, dst);
  2. Create the ForkJoinPool that will run the task.

    ForkJoinPool pool = new ForkJoinPool();
  3. Run the task.

    pool.invoke(fb);

For the full source code, including some extra code that creates the destination image file, see the ForkBlur example.

Standard Implementations

Besides using the fork/join framework to implement custom algorithms for tasks to be performed concurrently on a multiprocessor system (such as the ForkBlur.java example in the previous section), there are some generally useful features in Java SE which are already implemented using the fork/join framework. One such implementation, introduced in Java SE 8, is used by the java.util.Arrays class for its parallelSort() methods. These methods are similar to sort(), but leverage concurrency via the fork/join framework. Parallel sorting of large arrays is faster than sequential sorting when run on multiprocessor systems. However, how exactly the fork/join framework is leveraged by these methods is outside the scope of the Java Tutorials. For this information, see the Java API documentation.

Another implementation of the fork/join framework is used by methods in the java.util.streams package, which is part of Project Lambda scheduled for the Java SE 8 release. For more information, see the Lambda Expressions section.

JDK7新特性之fork/join框架的更多相关文章

  1. Java并发——Fork/Join框架

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4631466. ...

  2. Java并发——Fork/Join框架与ForkJoinPool

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4631466. ...

  3. Java 7 Fork/Join 框架

    在 Java7引入的诸多新特性中,Fork/Join 框架无疑是重要的一项.JSR166旨在标准化一个实质上可扩展的框架,以将并行计算的通用工具类组织成一个类似java.util中Collection ...

  4. 《java.util.concurrent 包源码阅读》22 Fork/Join框架的初体验

    JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人解释:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多线程的方式来执行一个任务. ...

  5. Fork/Join 框架-设计与实现(翻译自论文《A Java Fork/Join Framework》原作者 Doug Lea)

    作者简介 Dong Lea任职于纽约州立大学奥斯威戈分校(State University of New York at Oswego),他发布了第一个广泛使用的java collections框架实 ...

  6. 【转】Fork/Join框架测试

    Fork/Join框架介绍 下面使用该框架计算0-50000000000的和,并比较普通计算方法.Fork/Join框架.Java8新特性三种计算方式的计算时间: import java.time.D ...

  7. 013-多线程-基础-Fork/Join框架、parallelStream讲解

    一.概述 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 它同ThreadPoolExecut ...

  8. ☕【Java技术指南】「并发编程专题」Fork/Join框架基本使用和原理探究(基础篇)

    前提概述 Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行. 我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一 ...

  9. JAVA中的Fork/Join框架

    看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...

随机推荐

  1. Programming Collective Intelligence

    最近正在拜读 O'reilly出版的Programming Collective Intelligence,准备研究研究搜索引擎了,童鞋们,到时候会考虑公布源码哦!

  2. Centos6.4 安装NLTK

    NLTK 安装链接 http://www.nltk.org/install.html 不知道什么原因打不开pypi 的网站  http://pypi.python.org/pypi/setuptool ...

  3. PyQt4学习记录之事件和信号

    事件是任何 GUI程序中很重要的部分.所有 Python GUI 应用都是事件驱动的.一个应用对其生命期产生的不同的事件类型做出反应.事件是主要由应用的用户产生.但是,也可以通过其他方法产生,比如,网 ...

  4. 1037. Magic Coupon (25)

    #include<iostream> #include<vector> #include<stdio.h> #include<algorithm> us ...

  5. Oracle修改表空间大小

    在向orale数据库导入数据的时候报 ORA-01658: 无法为表空间 XXX中的段创建 INITIAL 区错误. Oracle我在创建表空间的时候初始化大小为200M,当数据库中数据量达到这个值, ...

  6. 进程(Process)和线程(Thread)的关系和区别

    Definition定义-------------Process进程是应用程序的一次运行活动:从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源.cpu时间片等资源的基本单位,为正在运行的 ...

  7. SelectList

    SelectList 构造函数 (IEnumerable, String, String, Object) 使用列表的指定项.数据值字段.数据文本字段和选定的值来初始化 SelectList 类的新实 ...

  8. iOS 获取手机的型号,系统版本,软件名称,软件版本

    转载自:http://www.2cto.com/kf/201210/162333.html   网上搜索出来的,记录下来以后使用方便: [java]//手机序列号      NSString* ide ...

  9. 深入浅出百度地图API开发系列(2):创建地图

    上一篇文章里,先介绍了一下百度地图API开发所涉及到的一些基础概念,包括投影,坐标系等基础概念,再有了这些基础后,我们可以开始开发自己的web地图了.先来个代码示例(建议大家都是用百度地图API大众版 ...

  10. 5.0:Spring-bean的加载

    内容来自<Spring深度解析>,之后的不一一复述! 在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎 ...