gpt4 book ai didi

java - 规范是否保证对顺序 Java 流的操作必须保留在当前线程中?

转载 作者:太空狗 更新时间:2023-10-29 22:58:33 24 4
gpt4 key购买 nike

规范是否保证所有对 sequential Java Streams 的操作都在当前线程中执行? (“forEach”和“forEachOrdered”除外)

我明确要求规范,而不是当前实现的功能。我可以自己研究当前的实现,不需要为此打扰您。但是实现可能会改变,并且还有其他实现。

我问是因为 ThreadLocals:我使用的框架在内部使用 ThreadLocals。即使像 company.getName() 这样的简单调用最终也会使用 ThreadLocal。我无法更改该框架的设计方式。至少不是在合理的时间内。

此处的规范似乎令人困惑。 the Package "java.util.stream" 的文档状态:

If the behavioral parameters do have side-effects, unless explicitly stated, there are no guarantees as to the visibility of those side-effects to other threads, nor are there any guarantees that different operations on the "same" element within the same stream pipeline are executed in the same thread.

...

Even when a pipeline is constrained to produce a result that is consistent with the encounter order of the stream source (for example, IntStream.range(0,5).parallel().map(x -> x*2).toArray() must produce [0, 2, 4, 6, 8]), no guarantees are made as to the order in which the mapper function is applied to individual elements, or in what thread any behavioral parameter is executed for a given element.

我会将其解释为:流上的每个操作都可能发生在不同的线程中。但是the documentation of "forEach" and "forEachOrdered"明确指出:

For any given element, the action may be performed at whatever time and in whatever thread the library chooses.

如果每个流操作都可能发生在未指定的线程中,那么该语句将是多余的。因此是否相反:串行流上的所有操作都保证在当前线程中执行,除了“forEach”和“forEachOrdered”?

我用谷歌搜索了关于“Java”、“Stream”和“ThreadLocal”组合的权威答案,但一无所获。关闭的东西是 Brian Goetz 的回答到 Stack Overflow 上的一个相关问题,但它是关于顺序的,而不是线程,它只是关于“forEach”,而不是其他流方法:Does Stream.forEach respect the encounter order of sequential streams?

最佳答案

我相信您正在寻找的答案没有那么明确,因为它取决于消费者和/或 split 者及其特征:

在阅读主要引用之前:

https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#stream

default Stream stream() Returns a sequential Stream with this collection as its source. This method should be overridden when the spliterator() method cannot return a spliterator that is IMMUTABLE, CONCURRENT, or late-binding. (See spliterator() for details.)

https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html#binding

Despite their obvious utility in parallel algorithms, spliterators are not expected to be thread-safe; instead, implementations of parallel algorithms using spliterators should ensure that the spliterator is only used by one thread at a time. This is generally easy to attain via serial thread-confinement, which often is a natural consequence of typical parallel algorithms that work by recursive decomposition. A thread calling trySplit() may hand over the returned Spliterator to another thread, which in turn may traverse or further split that Spliterator. The behaviour of splitting and traversal is undefined if two or more threads operate concurrently on the same spliterator. If the original thread hands a spliterator off to another thread for processing, it is best if that handoff occurs before any elements are consumed with tryAdvance(), as certain guarantees (such as the accuracy of estimateSize() for SIZED spliterators) are only valid before traversal has begun.

Spliterators 和消费者有他们的一组特征,这将定义保证。假设您在一条河流中经营。由于拆分器不应该是线程安全的,并且应该将元素处理到可能在其他线程中的其他拆分器,无论是否顺序,因此保证为空。但是,如果没有发生拆分,引号将导致以下结果:在一个拆分器下,操作将保留在同一线程中,任何导致拆分的事件都将导致假设为空,否则为真

关于java - 规范是否保证对顺序 Java 流的操作必须保留在当前线程中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50491371/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com