相关疑难解决方法(0)

Stream.forEach是否遵循顺序流的遭遇顺序?

Javadoc Stream.forEach表示(强调我的):

此操作的行为明确是不确定的.对于并行流管道,此操作不保证遵守流的遭遇顺序,因为这样做会牺牲并行性的好处.对于任何给定元素,可以在任何时间以及库选择的任何线程中执行该动作.如果操作访问共享状态,则它负责提供所需的同步.

Java 9 Early Access Javadoc中提供了相同的文本.

第一句("明确不确定")表明(但没有明确说明)此方法不会保留遭遇顺序.但是明确说明顺序没有保留的下一个句子是以"For parallel stream pipeline"为条件的,如果不管并行性如何应用该句子,那么这个条件就没有了.这让我不确定forEach是否会保留顺序流的顺序.

这个答案指出了流库实现调用的位置.sequential().forEach(downstream).这表明forEach旨在保留顺序流的顺序,但也可能只是库中的错误.

我通过使用forEachOrdered安全的方式回避了我自己的代码中的这种模糊性,但今天我发现NetBeans IDE的"使用功能操作"编辑器提示将转换

for (Foo foo : collection)
    foo.bar();
Run Code Online (Sandbox Code Playgroud)

collection.stream().forEach((foo) -> {
    foo.bar();
});
Run Code Online (Sandbox Code Playgroud)

如果forEach不保留遭遇顺序,则会引入错误.在我报告针对NetBeans的错误之前,我想知道库实际上保证了什么,并由源备份.

我正在寻找权威人士答案.这可能是图书馆实施中的一个明确的评论,关于Java开发邮件列表的讨论(谷歌没有找到任何东西,但我可能不知道这些神奇的词汇),或者是图书馆设计师的声明(其中我知道两个,Brian GoetzStuart Marks,积极参与Stack Overflow).(请不要回答"只是使用forEachOrdered" - 我已经这样做了,但我想知道代码是否错误.)

java java-8 java-stream

23
推荐指数
1
解决办法
1300
查看次数

Java,哪个线程是顺序流执行的?

在阅读有关流的文档时,我遇到了以下句子:

  • ...试图从行为参数中访问可变状态会给你一个错误的选择...如果你没有同步访问那个状态,你就有数据竞争,因此你的代码被破坏...... [1]

  • 如果行为参数确实有副作用...... [没有]保证在同一个线程中执行同一流管道中"相同"元素的不同操作.[2]

  • 对于任何给定元素,可以在任何时间以及库选择的任何线程中执行该动作.[3]

这些句子不区分顺序流和并行流.所以我的问题是:

  1. 在哪个线程中执行顺序流的管道?它始终是调用线程还是可以自由选择任何线程的实现?
  2. 在流是顺序的情况下,哪个线程是forEach终端操作的action参数?
  3. 使用顺序流时是否必须使用任何同步?

java foreach java-8 java-stream

8
推荐指数
1
解决办法
632
查看次数

标签 统计

java ×2

java-8 ×2

java-stream ×2

foreach ×1