parallelStream原理。

parallelStream是并行流,依赖jdk1.7出现的Fork/Join框架。

Fork/Join框架的核心是工作窃取(work-stealing)算法。那么什么是工作窃取算法呢?假如我们有一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应,比如A线程负责处理A队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。

ForkJoinPool是一个运行ForkJoinTask的线程池,同ThreadPoolExecutor一样,也继承了AbstractExecutorService。ForkJoinPool的每个工作线程都维护着一个工作队列,这是一个双端队列Deque,里面存放着任务ForkJoinTask。每个工作线程在运行过程中,产生的新任务会放到工作队列的队尾。工作线程在处理自己工作队列任务时,每次是从队尾取任务。当自己的工作队列清空后,会尝试去窃取其他工作队列的任务,且是从队首窃取。

并行流处理过程中,用的ForkJoinTask是CountedCompleter的几个子类,如forEach()操作对应的是ForEachTask,forEachOrdered()操作对应的是ForEachOrderedTask,reduce()操作对应的是ReduceTask。

以Lists.newArrayList(1, 2, 3).parallelStream().forEach(System.out::println);为例,用的ForkJoinPool实例是

跟到ForEachTask的compute()方法,ForEachTask 第283行,AbstractTask.suggestTargetSize(sizeEstimate);

AbstractTask的suggestTargetSize()方法实现是:

    public static long suggestTargetSize(long sizeEstimate) {
long est = sizeEstimate / LEAF_TARGET;
return est > 0L ? est : 1L;
}

其中,LEAF_TARGET值定义是

static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2;

这里就调用了ForkJoinPool的getCommonPoolParallelism()静态方法。ForkJoinPool有一个static块,里面调用ForkJoinPool的makeCommonPool()静态方法给静态的ForkJoinPool实例common赋值。makeCommonPool()方法内部调用了ForkJoinPool的private的构造方法,其中第一个参数并行度的值是CPU核心数-1。取CPU核心数的代码是Runtime.getRuntime().availableProcessors()。

        if (parallelism < 0 &&
(parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
parallelism = 1;
if (parallelism > MAX_CAP)
parallelism = MAX_CAP;

我们如果想用ForkJoinPool实现自己的业务,则需要继承ForkJoinTask。更简单点,只需继承ForkJoinTask的子类RecursiveTask或者RecursiveAction,重写compute()方法即可。

案例见:https://blog.csdn.net/niyuelin1990/article/details/78658251

ForkJoinPool及并行流解析的更多相关文章

  1. java8学习之收集器枚举特性深度解析与并行流原理

    首先先来找出上一次[http://www.cnblogs.com/webor2006/p/8353314.html]在最后举的那个并行流报错的问题,如下: 在来查找出上面异常的原因之前,当然得要一点点 ...

  2. Fork/Join框架与Java8 Stream API 之并行流的速度比较

    Fork/Join 框架有特定的ExecutorService和线程池构成.ExecutorService可以运行任务,并且这个任务会被分解成较小的任务,它们从线程池中被fork(被不同的线程执行)出 ...

  3. Java8新特性 并行流与串行流 Fork Join

    并行流就是把一个内容分成多个数据块,并用不同的线程分 别处理每个数据块的流. Java 8 中将并行进行了优化,我们可以很容易的对数据进行并 行操作. Stream API 可以声明性地通过 para ...

  4. JAVA8给我带了什么——并行流和接口新功能

    流,确定是笔者内心很向往的天堂,有他之后JAVA在处理数据就变更加的灵动.加上lambda表达不喜欢都不行.JAVA8也为流在提供另一个功能——并行流.即是有并行流,那么是不是也有顺序流.没有错.我前 ...

  5. jdk8--stream并行流

    stream的并行流要理解一个框架如下: 单线程,多线程和并行流对比 package com.atguigu.java8; import java.util.concurrent.ForkJoinPo ...

  6. list.stream().parallel() 并行流

    https://blog.csdn.net/u011001723/article/details/52794455/  :  parallel()其实就是一个并行执行的流.它通过默认的ForkJoin ...

  7. java8新特性——并行流与顺序流

    在我们开发过程中,我们都知道想要提高程序效率,我们可以启用多线程去并行处理,而java8中对数据处理也提供了它得并行方法,今天就来简单学习一下java8中得并行流与顺序流. 并行流就是把一个内容分成多 ...

  8. Stream的顺序流与并行流

    /** * @auther hhh * @date 2019/1/2 22:52 * @description */ public class StreamAPI2 { /** * 流的特性:支持并行 ...

  9. 三、并行流与串行流 Fork/Join框架

    一.并行流概念: 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性的通过pa ...

随机推荐

  1. 运行RGB-DSLAM的一些报错及处理方法

    part 4 报错‘create’ is not a menber of 'CV::FeatureDetector::create(detector.c_str()); 查看opencv版本 修改Cm ...

  2. 深入理解java:4.3. 框架编程之MyBatis原理深入解析

    1 引言 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架.再而论述Mybatis作为一个数据持久层框架本身有待改进之处. 2 ...

  3. poj1042(贪心+枚举)

    题目链接:https://vjudge.net/problem/POJ-1042 题意:给n个湖,给出每个湖第一次打捞时鱼的数量f[i],每单位时间鱼减少的数量d[i],从湖i到湖i+1用时t[i], ...

  4. Boruvka

    大概是这样的:一开始图中有\(n\)个连通块,每次操作我们选出各个连通块连出去的最短的边(如果有相同边权的边的话可以把序号作为第二关键字),然后把这些边加入最小生成树. 最坏的情况下每次操作都会让当前 ...

  5. laravel修改用户模块的密码验证

    做项目的时候,用户认证几乎是必不可少的,如果我们的项目由于一些原因不得不使用 users 之外的用户表进行认证,那么就需要多做一点工作来完成这个功能. 现在假设我们只需要修改登录用户的表,表名和表结构 ...

  6. Android引用多媒体

    res目录下,创建raw目录(Android会自动识别这个目录),如果自己创建的目录,可能无效底下的mp3格式,mp4格式的文件名必须小写. 引用方式: mediaPlayer = MediaPlay ...

  7. Git+码云安装

    注册码云 1.1 下载git https://git-scm.com 1.2 安装 git安装一直next 下一步就行 1.3 测试 1.4 git原理

  8. HNUSTOJ-1512 奇怪的导弹(暴力)

    1512: 奇怪的导弹 时间限制: 3 Sec  内存限制: 32 MB提交: 31  解决: 13[提交][状态][讨论版] 题目描述 最近国际形势比较紧张,就拿中国来说,比如南海问题,钓鱼岛事件等 ...

  9. 洛谷 - P3469 - BLO-Blockade - 割点

    https://www.luogu.org/problem/P3469 翻译:一个原本连通的无向图,可以删除图中的一个点,求因为删除这个点所导致的不连通的有序点对的数量.或者说,删去这个点之后,各个连 ...

  10. python网络爬虫(2)回顾Python编程

    文件写入 def storFile(data,fileName,method='a'): with open(fileName,method,newline ='') as f: f.write(da ...