问题描述
前提:我已经阅读了和其他人,但我需要一些澄清。
Premise: I've already read this question and others, but I need some clarifications.
我理解 Stream.forEach
方法使处理并行流时的差异(不仅如此),这也解释了为什么这个
I understand that Stream.forEach
method makes the difference (not only) when dealing with parallel streams, and this explains why this
//1
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.forEachOrdered(item -> System.out.print(item));
打印
one two three four five six
但是当谈到中间操作时,订单是流并行化时不再保证。所以这段代码
But when it comes to intermediate operations, the order is not guaranteed anymore when stream is parallelized. So this code
//2
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.peek(item -> System.out.print(item))
.forEachOrdered(item -> System.out.print(""));
将打印类似
four six five one three two
说<$是否正确c $ c> forEachOrdered 方法只影响自己执行中元素的顺序?直观地说,我想 // 1
示例与
Is it correct to say that forEachOrdered
method only affects order of elements in its own execution? Intuitively, I'm thinking of //1
example being exactly the same as
//3
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.peek(item -> System.out.print("")) //or any other intermediate operation
.sequential()
.forEach(item -> System.out.print(item));
我的直觉是错的吗?我错过了关于整个机制的一些内容吗?
Is my intuition wrong? Am I missing something about the whole mechanism?
推荐答案
你是对的,因为<$ c $的行动所做的保证是正确的c> forEachOrdered 仅适用于该操作而不适用于其他操作。但是假设这与 .sequential()。forEach(...)
相同是错误的。
You are right in that the guarantees made for the action of forEachOrdered
only apply to that action and nothing else. But it’s wrong to assume that this is the same as .sequential().forEach(…)
.
sequential
会将整个流管道转为顺序模式,因此传递给 forEach
的动作将由同一个线程执行,还有前面的 peek
的动作。对于大多数中间操作, parallel
或 sequential
的确切位置是无关紧要的,指定两者都没有意义,因为只有最后一个一个将是相关的。
sequential
will turn the entire stream pipeline into sequential mode, thus, the action passed to forEach
will be executed by the same thread, but also the preceding peek
’s action. For most intermediate operations, the exact placement of parallel
or sequential
is irrelevant and specifying both makes no sense as only the last one will be relevant.
此外,使用 forEach
时,仍然没有保证订购,即使它没有任何当前实施的后果。 的文档说明:
The documentation of Stream.forEachOrdered
states:
因此,动作可能会被不同的线程调用,如 Thread.currentThread()
所感知,但不会同时运行。
此外,如果流有遭遇订单,它将在此处重组。 揭示了遇到订单和处理订单的区别。
So the action may get invoked by different threads, as perceivable by Thread.currentThread()
but not run concurrently.Further, if the stream has an encounter order, it will get reconstituted at this place. This answer sheds some light one the difference of encounter order and processing order.
这篇关于Java Stream:forEach和forEachOrdered之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!