【问题标题】:Parallelism and Flatmap in Java 8 StreamsJava 8 Streams 中的并行性和平面图
【发布时间】:2014-06-25 14:24:36
【问题描述】:

考虑以下示例:

    IntStream.of(-1, 1)
             .parallel()
             .flatMap(i->IntStream.range(0,1000).parallel())
             .forEach(System.out::println);

是否将内部标志设置为并行有关系吗?无论我是否离开,结果看起来都非常相似。

还有,为什么代码 (ReferencePipeline) 会按顺序排列映射?

我被line弄糊涂了:

result.sequential().forEach(downstream);

【问题讨论】:

  • 好吧,根据代码We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it 中的注释,我假设他们不必将其实现为result.sequential().forEach(downstream),并且可以使用并行实现来获得更好的性能。跨度>

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


【解决方案1】:

在当前的JDK(jdk1.8.0_25)中,答案是否定的,把inner flag设置成parallel也没关系, 因为即使您设置了它,.flatMap() 实现集也会在此处将流返回到 sequential

result.sequential().forEach(downstream);

("result" 是内部流,它是 sequential() 方法的文档说:返回一个等效的顺序流。 可能返回自身,因为流已经是顺序的,或者因为底层流状态被修改为顺序。)

在大多数情况下,可能没有努力使内部流平行;如果外部流的项目数至少与可以并行运行的线程数相同(我的计算机中的ForkJoinPool.commonPool().getParallelism() = 3)。

【讨论】:

  • 我有点不同意最后的说法。仅当每个外部元素的计算负载大致相等时才是正确的。
  • 假设您正在制作一个网络爬虫,外部流在网站之上,内部在他们的文字或其他内容之上。如果其中一个网站比其他网站大得多,这可能意味着您最终会得到一个基本顺序的程序。理解正确吗?
【解决方案2】:

对于像我这样迫切需要并行化 flatMap 并需要一些实用解决方案的人来说,不仅仅是历史和理论。

我想出的最简单的解决方案是手动进行展平,基本上是将其替换为map + reduce(Stream::concat)

已经在另一个帖子中发布了带有详细信息的答案: https://stackoverflow.com/a/66386078/3606820

【讨论】:

    猜你喜欢
    • 2017-04-27
    • 2020-01-18
    • 2012-08-27
    • 2020-01-11
    • 2018-12-22
    • 2015-07-09
    • 1970-01-01
    • 2014-11-05
    • 2018-05-10
    相关资源
    最近更新 更多