Java 8中parallelStream的变异减少

时间:2018-06-15 04:36:41

标签: java parallel-processing java-8 java-stream reduce

<Effective Java> (Third Edition)中的

Joshua Bloch 提及

  

Stream的collect方法执行的操作(称为 mutable reduction )不适合并行,因为组合集合的开销很大。

我在Mutable reduction上阅读了文档,但我仍然不太确定为什么减少并不是并行的好选择。是synchronization吗?

正如@Ravindra Ranwala指出的那样(我也在Reduction, concurrency, and ordering文档中看到了这一点):

  

并行执行操作实际上可能适得其反。这是因为组合步骤(通过键将一个Map合并到另一个Map)对于某些Map实现来说可能昂贵

如果是这样,那么还有其他主要因素我们需要关注的可能会导致性能低下吗?

1 个答案:

答案 0 :(得分:5)

不, synchronization无关。假设您有100万个Person个对象,需要查找居住在纽约的所有people个人。因此,典型的流管道将是

people.parallelStream()
    .filter(p -> p.getState().equals("NY"))
    .collect(Collectors.toList());

考虑并行执行此查询。假设我们有10个线程并行执行它。每个线程都会将自己的数据集累积到一个单独的本地容器中。最后,合并10个结果容器以形成一个大容器。此合并的成本很高,并且是并行执行引入的附加步骤。因此,并行执行可能并不总是更快。有时,顺序执行可能比并行计数器部分更快。

所以总是从顺序执行开始。如果这只是有意义的话,你可能会在稍后的某个时间点回到它的平行对手。