Java8 ParallelStream
ParallelStream
并行流就是一个把内容拆分成多个数据块,用不同线程分别处理每个数据块的流。对收集源调用parallelStream方法就能将集合转换为并行流。
并行流
并行流和顺序流转换
parallel 和 sequential
Integer reduce = Stream.iterate(0, n -> n + 2).limit(10000).reduce(1, Integer::sum);
// 将顺序流转化为并行流
Integer reduce1 = Stream.iterate(0, n -> n + 2).limit(10000).parallel().reduce(1, Integer::sum);
// 将并行流转为顺序流
Integer reduce2 = Stream.iterate(0, n -> n + 2).limit(10000).parallel().map(integer -> integer + 2).sequential().reduce(1, Integer::sum);
最后一次parallel或sequential调用会影响整个流水线
配置并行流使用的线程池:
并行流内部使用了默认的ForkJoinPool。它默认的线程数量就是你的处理器数量,这个值是由Runtime.getRuntime().availableProcessors()得到的。
可以通过系统属性java.util.concurrent.ForkJoinPool.common.parallelism来修改线程池大小
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");
System.out.println( System.getProperty("java.util.concurrent.ForkJoinPool.common.parallelism"));这是一个全局设置,因此它会对代码中所有的并行流产生影响。反过来说,目前我们还无法专为某个并行流指定这个值。一般而言,让ForkJoinPool的大小等于处理器数量是个不错的默认值,除非你有很充足的理由,否则强烈建议你不要修改它。
正确的姿势使用并行流
并行流并不总是比顺序流快。所以正确的姿势使用并行流是尤为重要的,不然适得其反。
决定某个特定情况下是否有必要使用并行流。可以参考一下几点建议
如果有疑问,测量。并行流有时候会和你的直觉不一致,所以在考虑选择顺序流还是并行流时,很重要的建议就是用适当的基准来检查其性能。
留意装箱。自动装箱和拆箱操作会大大降低性能。Java 8中有原始类型流(IntStream、LongStream和DoubleStream)来避免这种操作,但凡有可能都应该用这些流
有些操作本身在并行流上的性能就比顺序流差。特别是limit和findFirst等依赖于元素顺序的操作,它们在并行流上执行的代价非常大。例如,findAny会比findFirst性能好,因为它不一定要按顺序来执行。你总是可以调用unordered方法来把有序流变成无序流。那么,如果你需要流中的N个元素而不是专门要前N个的话,对无序并行流调用limit可能会比单个有序流(比如数据源是一个List)更高效。
考虑流的操作流水线的总计算成本。设N是要处理的元素的总数,Q是一个元素通过流水线的大致处理成本,则N*Q就是这个对成本的一个粗略的定性估计。Q值较高就意味着使用并行流时性能好的可能性比较大。
对于较小的数据量,选择并行流几乎从来都不是一个好的决定。并行处理少数几个元素的好处还抵不上并行化造成的额外开销。
考虑流背后的数据结构是否易于分解。例如,ArrayList的拆分效率比LinkedList高得多,因为前者用不着遍历就可以平均拆分,后者则必须遍历。另外,用range工厂方法创建的原始类型流也可以快速分解。可以参考一下表格:
数据源 性能 ArrayList 极佳 LinkedList 差 IntStrean.range 极佳 Strean.iterate 差 HashSet 好 TreeSet 好 流自身的特点以及流水线中的中间操作修改流的方式,都可能会改变分解过程的性能。例如,一个SIZED流可以分成大小相等的两部分,这样每个部分都可以比较高效地并行处理,但筛选操作可能丢弃的元素个数无法预测,从而导致流本身的大小未知。
还要考虑终端操作中合并步骤的代价是大是小(例如Collector中的combiner方法)。如果这一步代价很大,那么组合每个子流产生的部分结果所付出的代价就可能会超出通过并行流得到的性能提升。
Java8 ParallelStream的更多相关文章
- 【Java】关于Java8 parallelStream并发安全的思考
背景 Java8的stream接口极大地减少了for循环写法的复杂性,stream提供了map/reduce/collect等一系列聚合接口,还支持并发操作:parallelStream. 在爬虫开发 ...
- Java8 parallelStream浅析
JAVA8中引入了lamda表达式和Stream接口.其丰富的API及强大的表达能力极大的简化代码,提升了效率,同时还通过parallelStream提供并发操作的支持,本文探讨parallelStr ...
- Java8 parallelStream与迭代器Iterator性能
定义一个测试类 public class TestParallelStream { private List<Integer> list; private int size; privat ...
- [源码解析] 当 Java Stream 遇见 Flink
[源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...
- java8的parallelStream提升数倍查询效率
业务场景 在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数,订单总金额,支出总金额等...这些业务通常都不是存在同一张表中,我们需要依次查询出来然后封装成所需要的对象返回给前端 ...
- java8中parallelStream提升数倍查询效率是怎样实现的,来看看这篇文章
作者:我恰芙蓉王 原文:https://www.cnblogs.com/-tang/p/13283216.html 业务场景 在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数, ...
- 避坑 | Java8使用并行流(ParallelStream)注意事项
示例分析 /** * 避坑 | Java8使用并行流(ParallelStream)注意事项 * * @author WH.L * @date 2020/12/26 17:14 */ public c ...
- Java8使用并行流(ParallelStream)注意事项
Java8并行流ParallelStream和Stream的区别就是支持并行执行,提高程序运行效率.但是如果使用不当可能会发生线程安全的问题.Demo如下: public static void co ...
- java8 新特性parallelStream 修改默认多线程数量
parallelStream默认使用了fork-join框架,其默认线程数是CPU核心数. 通过测试实践,发现有两种方法来修改默认的多线程数量: 1.全局设置 在运行代码之前,加入如下代码: Syst ...
随机推荐
- “随手记”开发记录day17
继续开发账单的图形展示这一部分,丰富“随手记”的显示方法,对我们的APP进行添砖加瓦.
- “随手记”开发记录day04
今天完成了添加收入和支出的页面,其实挺简单的就是里面的那个图表有些难搞,你得把每个图标和文字对应起来 挺费事的 话不多说,上效果 其中点击旋转按钮转换收入支出是我们找了好久才找出来这个方法的,太不容易 ...
- 14、Cahin of Responsibility 责任链 COR设计模式
1.责任链模式 chain of responsibility 责任链模式 责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某 ...
- Go 中的动态作用域变量
这是一个 API 设计的思想实验,它从典型的 Go 单元测试惯用形式开始: func TestOpenFile(t *testing.T) { f, err := os.Open("notf ...
- CSS学习第三天
定位布局: 相对定位:相对于自身的位置进行偏移position需要搭配left right top bottom position: relative; 绝对定位:相对于有position属 ...
- C#LeetCode刷题-哈希表
哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串 24.2% 中等 18 四数之和 ...
- 从零开始,Windows操作系统下的超详细的阿里云发布项目过程
==================== 步骤0: 购买阿里云服务器 ==================== 0.1 从来没有搞过外网部署的我,当然是先买服务器了,感谢很多小伙伴的帮忙 0.2 登录 ...
- DRF内置认证组件之自定义认证系统
自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...
- 微信小程序自动化测试最佳实践(附 Python 源码)
本文为霍格沃兹测试学院测试大咖公开课<微信小程序自动化测试>图文整理精华版. 随着微信小程序的功能和生态日益完善,很多公司的产品业务形态逐渐从 App 延升到微信小程序.微信公众号等.小程 ...
- CODING DevOps 微服务项目实战系列第一课,明天等你
CODING DevOps 微服务项目实战系列第一课<DevOps 微服务项目实战:DevOps 初体验>将由 CODING DevOps 开发工程师 王宽老师 向大家介绍 DevOps ...