使用带有并行流的forEachOrdered的好处

时间:2017-11-16 18:33:26

标签: java java-8

Oracle官方文档说:

  

请注意,如果使用,可能会失去并行性的好处   与并行流的forEachOrdered一样的操作。   Oracle - Parallelism

如果我们失去并行性,为什么有人会将forEachOrdered用于并行流?

3 个答案:

答案 0 :(得分:9)

取决于情况,使用ForEachOrdered不会失去所有并行性的好处。

假设我们有这样的东西:

stringList.parallelStream().map(String::toUpperCase)
                           .forEachOrdered(System.out::println);

在这种情况下,我们可以保证ForEachOrdered终端操作将在遇到命令中以大写字母打印出字符串但是我们不应该假设元素将被传递给map中间操作的顺序与它们被选中进行处理的顺序相同。 map操作将由多个线程同时执行。所以人们仍然可以从并行性中受益,但这只是我们没有充分发挥并行性的潜力。总而言之,我们 应该使用ForEachOrdered,这对于按照流的遭遇顺序执行操作很重要。

按照您的评论进行修改:

  

当您跳过map操作时会发生什么?我更感兴趣   在forEachOrdered

之后parallelStream()

如果您指的是以下内容:

 stringList.parallelStream().forEachOrdered(action);

在做这样的事情时没有任何好处我怀疑这是设计师在决定创建方法时的想法。在这种情况下,做更有意义:

stringList.stream().forEach(action);

扩展您的问题“如果我们失去并行性,为什么有人会使用带并行流的forEachOrdered”,比如说你想对每个元素执行一个关于流遭遇顺序的动作;在这种情况下你需要使用 forEachOrdered,因为forEach终端操作是非确定性的并行使用时因此有一个版本< em>顺序流和一个专门用于并行

答案 1 :(得分:1)

我真的没有在这里得到问题。 为什么?因为你别无选择 - 你有这么多的数据,并行流将帮助你(这仍然需要证明);但是你仍然需要保留顺序 - 因此forEachOrdered。请注意,文档说可能而非 肯定会丢失 - 您必须进行衡量和查看。

答案 2 :(得分:0)

我发现stream()。forEachOrdered()比其并行对应物快约50%。另外,并行的一个使用来自公共fork-join线程池的至少一个线程,这是在JVM中运行的其他并行流的一个线程。

public static void main(String[] args) { long start = System.currentTimeMillis(); IntStream.range(0,10000000).parallel().forEachOrdered(i -> { //System.out.println(Thread.currentThread().getName()); int p = 1 * 1 ; }); System.out.println((System.currentTimeMillis() - start)); }