目录标题
[Q&A] 什么是并行流?
并行流就是一个把内容分成多个数据块,并用不同的线程分别处理每个数据块的流。这样一来,你就可以自动把给定操作的工作负荷分配给多核处理器的所有内核,让它们都忙起来。
[Q&A] 如何把流转换成并行流?
对顺序流调用parallel
方法。它在内部实际上就是设了一个boolean
标志,表示你想让调用parallel
之后进行的所有操作都并行执行。类似地,你只需要对并行流调用sequential
方法就可以把它变成顺序流。
public static long parallelSum(long n) {
return Stream.iterate(1L, i -> i + 1).limit(n)
.parallel() ←将流转换为并行流
.reduce(0L, Long::sum);
}
[Q&A] 串行并行可以随意切换吗?
不可以!! 你可能以为把这两个方法结合起来,就可以更细化地控制在遍历流时哪些操作要并行执行,哪些要顺序执行。但是在本例中,流水线会并行执行,因为最后调用的是它。
# 反例
stream.parallel().filter(...)
.sequential() ←─把流变成顺序流
.map(...)
.parallel() ←─把流变成并行流
.reduce();
[Q&A] 并行流用的线程是从哪儿来的?有多少个?怎么自定义这个过程呢?
并行流内部使用了默认的ForkJoinPool
,它默认的线程数量就是你的处理器数量,这个值是由Runtime.getRuntime().availableProcessors()
得到的。你可以通过系统属性parallelism来改变线程池大小
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");
这是一个全局设置,因此它将影响代码中所有的并行流。反过来说,目前还无法专为某个并行流指定这个值。一般而言,让ForkJoinPool
的大小等于处理器数量是个不错的默认值,除非你有很好的理由,否则我们强烈建议你不要修改它。
[Q&A] 如何高效使用并行流?
1、 测试很重要,改完要测试性能。
2、 留意装箱。自动装拆箱会大大降低性能。尽可能用(IntStream
、LongStream
、DoubleStream
)
3、 有些操作本身在并行流上的 性能 就比顺序流差。例如多用findAny
少用findFirst
。
分支/合并框架
[实践总结] 通过累加求和来学习 分支/合并框架
-----------------------------------------------------------------------------读书笔记摘自 书名:Java 8实战 作者:[英] Raoul-Gabriel Urma [意] Mario Fusco [英] Alan M