一、简介

在hadoop的分布式计算框架MapReduce中,会经过两个过程Map过程和reduce过程。Map过程将任务并行计算,reduce汇总并行计算的结果,如图:

MapReduce是在分布式环境中做分布式计算的,JDK1.7+以后再单机环境中也可以做类似的操作,它提供了一种ForkJoin框架。

ForkJoin框架中,fork()操作将任务异步并行执行(类似生成一个Map操作),join()操作等待异步并行的结果,你可以将并行结果进行汇总(类似reduce操作),并通过Future等方式获取异步线程的执行结果,如图:

JDK文档:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveTask.html

ForkJoin框架可以将一个任务通过不断地分解,并行地执行更多的任务。在这种方式下,你需要合理控制它的分解程度,因为你可能一次性爆发非常多的线程消耗大量的资源,会适得其反。

二、代码示例

以下代码示例对一个集合内的数据进行加法运算,我们将集合不断地拆分成两两加法,然后并行执行汇总结果。最后通过Future获取异步结果

这里我们采用继承RecursiveTask<T>的方式来编写实现类,因为我们需要返回值,其泛型即返回值。

如果你的任务不需要返回值,你可以继承RecursiveAction来实现。

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask; public class ForkJoinDemo extends RecursiveTask<Integer> { private List<Integer> nums; public ForkJoinDemo(List<Integer> nums) {
this.nums = nums;
} @Override
protected Integer compute() {
// 如果只有一个数据,直接返回
if (nums.size() == 1) {
return nums.get(0);
// 如果两个数据,相加
} else if (nums.size() == 2) {
return nums.get(0) + nums.get(1);
// 否则拆分任务
} else {
// 拆分成两个任务异步执行,并等待异步结果
int result1 = new ForkJoinDemo(nums.subList(0, nums.size()/2)).fork().join();
int result2 = new ForkJoinDemo(nums.subList(nums.size()/2, nums.size())).fork().join();
// 汇总结果
int total = result1 + result2;
// 返回汇总结果
return total;
}
} public static void main(String[] args) throws ExecutionException, InterruptedException {
// 数据准备
Integer[] nums = {1,2,3,4,5,6,7,8,9};
List<Integer> list = Arrays.asList(nums);
// 初始化fork任务
ForkJoinDemo forkJoinDemo = new ForkJoinDemo(list);
// 初始化线程池
ForkJoinPool pool = new ForkJoinPool();
// 提交任务
Future<Integer> future = pool.submit(forkJoinDemo);
// 阻塞获取返回值
System.out.println(future.get());
}
}

最后输出:

45

在实际应用场景中,最麻烦的地方可能会是在于如何对要处理的数据进行划分。以上示例中,我们可以对集合按照大小进行切分,但如果是字符串或者流等数据。你需要注意,如何划分,以及在划分过程中,不会让数据因为划分而导致部分或者全部失效

十八、fork/join框架的更多相关文章

  1. 聊聊并发(八)——Fork/Join框架介绍

      作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...

  2. 转:聊聊并发(八)——Fork/Join框架介绍

    1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过 ...

  3. JAVA中的Fork/Join框架

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

  4. JDK7新特性之fork/join框架

    The fork/join framework is an implementation of the ExecutorService interface that helps you take ad ...

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

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

  6. Java并发编程--Fork/Join框架使用

    上篇博客我们介绍了通过CyclicBarrier使线程同步,可是上述方法存在一个问题,那就是假设一个大任务跑了2个线程去完毕.假设线程2耗时比线程1多2倍.线程1完毕后必须等待线程2完毕.等待的过程线 ...

  7. 使用Java7提供Fork/Join框架

    在Java7在.JDK它提供了多线程开发提供了一个非常强大的框架.这是Fork/Join框架.这是原来的Executors更多 进一步,在原来的基础上添加了并行分治计算中的一种Work-stealin ...

  8. 使用Java7提供的Fork/Join框架

    http://blog.csdn.net/a352193394/article/details/39872923 使用Java7提供的Fork/Join框架 2014-10-07 23:55 4818 ...

  9. 实现ThreadFactory接口生成自定义的线程给Fork/Join框架

    Fork/Join框架是Java7中最有趣的特征之一.它是Executor和ExecutorService接口的一个实现,允许你执行Callable和Runnable任务而不用管理这些执行线程.这个执 ...

  10. Java 7 Fork/Join 框架

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

随机推荐

  1. RHEL 7 下内存管理小记

    RHEL 7 下内存管理小记 一.Overview 众所周知,在 Linux 操作系统中有三个目录非常有趣好玩. /dev /run /proc 一个个解释下,/dev 用于对特殊设备(BTW:特殊设 ...

  2. jee-oxygen版eclipse的安装与卸载 maven配置

    Eclipse 是一个开放源代码的.基于Java的可扩展开发平台,是大部分JAVA编程学习者入门的编程工具.Eclipse 是开发java的一个工具,Eclipse需要JDK中的JRE支持才能启动,所 ...

  3. Linux磁盘分区、挂在

    分区基础知识分区的方式:1) mbr分区:1.最多支持四个主分区2.系统只能安装在主分区3.扩展分区要占一个主分区4.MBR最大只支持2TB,但拥有最好的兼容性2) gtp分区:1.支持无限多个主分区 ...

  4. shell-007:数据库备份,本地保留7天,远程机器保留一个月

    ## #!/bin/bash d1=`date +%w` # 以周几有变量 d2=`date +%d` # 以每月第几天为变量 local_bakdir=/bak/mysql # 本地备份目录 rem ...

  5. sql自查询各种状态数据总和

  6. 3.1)DFM-塑胶件设计总章

    本章目的:各种塑胶工艺了解,DFM-塑胶件的设计准则是依据哪种工艺. 1.塑胶概念 塑胶的定义(美国塑料工业协会): 塑胶主要由碳.氧.氢和氮及其他有机或无机元素所构成,成品为固体,在制造过程中是熔融 ...

  7. springcloud(四)-Eureka Server集群

    Eureka Server的高可用 这一节我们接着上一节说. 有分布式应用开发经验的朋友应该发现,前文编写的单节点Eureka Server并不适合线上生产环境.Eureka Client会定时连接E ...

  8. HttpClient 工具类

    package com.sys.utils; import java.io.IOException; import java.net.URI; import java.util.ArrayList; ...

  9. java基本编译

    1.java语言严格区分大小写:1个源文件其中最多只能有一个public类:源文件必须和public类同名:每个类对应一个class字节码,且同名. 2.编译.   javac -d dir Hell ...

  10. Android字符串及字符串资源的格式化

    为什么要写这一篇随笔呢?最近做项目的过程中,遇到很多页面在要显示文本时,有一部分是固定的文本,有一部分是动态获取的,并且格式各式各样.一开始采取比较笨的办法,把他拆分成一个个文本控件,然后对不同的控件 ...