Stream提供了parallel 方法,可以简单的实现并行处理。但是想要真的利用stream 写出出正确快速的实现,还是有很多地方要注意的。
安全问题:
当我们在使用stream 时,首先要保证的是安全问题,如果结果都执行错了,那代码执行的再快也没有了意义。
安全性失败可能是因为并行的pipeline使用了映射、过滤器或者程序员自己编写的其他函数对象,并且没有遵守它们的规范。当我们在使用stream 实现并行流时,一定要确保后续的方法是互不干扰且无状态的。否则在实际的运行过程中可能会因为资源竞争或互相影响状态,导致结果出错。-
性能问题
- 1.引入并行流会引起额外的开销,就像线程的频繁上下文切换会导致额外的性能开销一样,当数据在多个cpu中的处理时间小于内核之间的传输时间,使用并行流也就没有什么意义了。
- 2.如果Stream是通过Iterator创建的,或者使用了中间操作的limit,那么并行pipeline也不能提高性能
- 3.在Stream上通过并行获得性能,最好是通过ArrayList、HashMap、HashSet和ConcurrentHashMap实例,数组,int范围和long范围等。主要原因是,这些数据结构具有优异的引用局部性,序列化的元素引用一起保存在内存中。 他们能被轻松准确地切割成任意块,更容易并行分工。具有最佳引用局部性的数据结构是基本类型数组,因为数据是相邻存储于内存的。
- 4.Stream pipeline的终止操作本质上也影响了并发执行的效率。在终止操作有大量依赖顺序的操作时,并行效率就会大受影响。并行较好的终止操作有reduce、min、max、count、sum、anyMatch、allMatch和noneMatch。
Stream的parallel 方法使程序员可以更容易的写出并行处理的代码,但是在实现之前,必须要思考安全性并验证性能是否真的有提升。
系统中我印象中最典型的应用,是新竹实现的一个多线程同步调用外部接口的功能,也在retro 时分享过,满足线程见互不干扰且方法中无状态,并且确实能带来性能上的显著提升。