java - 规范是否保证对顺序 Java 流的操作必须保留在当前线程中?
问题描述
规范是否保证对顺序Java 流的所有操作都在当前线程中执行?(“forEach”和“forEachOrdered”除外)
我明确要求规范,而不是当前实现的功能。我可以自己研究当前的实现,不需要为此打扰您。但是实现可能会改变,并且还有其他实现。
我之所以问是因为 ThreadLocals:我使用了一个在内部使用 ThreadLocals 的框架。即使是像 company.getName() 这样的简单调用最终也会使用 ThreadLocal。我无法更改该框架的设计方式。至少不是在一段理智的时间内。
该规范在这里似乎令人困惑。包“java.util.stream”的文档指出:
如果行为参数确实有副作用,除非明确说明,否则不能保证这些副作用对其他线程的可见性,也不能保证对同一流管道内“相同”元素的不同操作在同一个线程中执行。
...
即使管道被约束以产生与流源的遇到顺序一致的结果(例如, IntStream.range(0,5).parallel().map(x -> x*2).toArray( ) 必须产生 [0, 2, 4, 6, 8]),不保证映射器函数应用于单个元素的顺序,或在哪个线程中为给定元素执行任何行为参数。
我将其解释为:流上的每个操作都可能发生在不同的线程中。但是“forEach”和“forEachOrdered”的文档明确指出:
对于任何给定的元素,可以在库选择的任何时间和任何线程中执行操作。
如果每个流操作都可能发生在未指定的线程中,那么该语句将是多余的。因此是否相反:串行流上的所有操作都保证在当前线程中执行,除了“forEach”和“forEachOrdered”?
我搜索了有关“Java”、“Stream”和“ThreadLocal”组合的权威答案,但一无所获。关闭的事情是Brian Goetz对 Stack Overflow 上一个相关问题的回答,但它是关于顺序,而不是线程,它只是关于“forEach”,而不是其他流方法:Stream.forEach 是否尊重遇到顺序流的顺序?
解决方案
我相信您正在寻找的答案没有那么明确,因为它将取决于消费者和/或拆分器及其特征:
在阅读主要引文之前:
https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#stream
默认 Stream stream() 返回以此集合为源的顺序流。当 spliterator() 方法无法返回 IMMUTABLE、CONCURRENT 或后期绑定的拆分器时,应覆盖此方法。(有关详细信息,请参阅 spliterator()。)
https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html#binding
尽管它们在并行算法中有明显的用途,但分离器并不期望是线程安全的。相反,使用拆分器的并行算法的实现应确保拆分器一次仅由一个线程使用。这通常很容易通过串行线程限制来实现,这通常是通过递归分解工作的典型并行算法的自然结果。调用 trySplit() 的线程可以将返回的 Spliterator 移交给另一个线程,该线程又可以遍历或进一步拆分该 Spliterator。如果两个或多个线程在同一个拆分器上同时操作,拆分和遍历的行为是不确定的。如果原始线程将拆分器交给另一个线程进行处理,
Spliterators 和 Consumers 有他们的一组特征,这将定义保证。让我们假设您在一个流中操作。由于拆分器不应该是线程安全的,并且应该将元素处理给可能在其他线程中的其他拆分器,无论是否连续,因此保证为空。但是,如果没有拆分,引号将导致以下情况:在一个拆分器下,操作将保留在同一线程中,任何导致拆分的事件都将导致假设为空,否则为真
推荐阅读
- sqlite - 如何在我的费用计划应用程序中查询特定月份的交易
- javascript - 将 HTML 附加到 iframe
- file - 如何使用 Lua 正确检查文件格式?
- c - XY 5x5 板移动的高效伪代码
- django - 如何将我的模板传递到 Django Userena 登录/注册视图
- javascript - 在 useEffect 挂钩中使用 matchMedia 会导致无限渲染
- python - 为每个标题创建一个包含列的 csv
- java - 需要一个 org.springframework.security.authentication.AuthenticationManager 类型的 bean
- mysql - 允许远程访问 Windows 10 上的 Mysql Server 8
- mongodb - MongoDB对多列求和的聚合操作