前提:我已经读过这个问题和其他问题,但我需要一些澄清。
我理解这条流。forEach方法不仅在处理并行流时起作用,这也解释了为什么
//1
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.forEachOrdered(item -> System.out.print(item));
印刷品
one two three four five six
但当涉及到中间操作时,当流被并行化时,顺序就不再有保障了。所以这个代码
//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
说forEachOrded
方法只影响其自身执行中元素的顺序是正确的吗?直观地说,我认为//1
示例与
//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));
我的直觉错了吗?我是不是遗漏了整个机制的一些东西?
#3代码在概念上并不等同于#1,因为parallel()
或sequential()
调用影响整个流,而不仅仅是后续操作。所以在#3的情况下,整个过程将按顺序进行。实际上#3案例类似于流API的早期设计,当您实际上可以更改并行/顺序模式时。这被认为是不必要的复杂化(实际上增加了问题,例如,请参见本讨论),因为通常您只需更改模式即可使终端操作有序(但不一定是顺序的)。因此,添加了forEachOrdered()
,并更改了parallel()/sequential()
语义,以影响整个流(请参见此变更集)。
基本上你是对的:在并行流中,中间操作没有顺序保证。如果需要按特定顺序执行,则必须使用顺序流。
你是对的,对forEachOrdered行动的保证只适用于该行动,其他什么都不适用。但是,假设这与相同是错误的。顺序()。forEach(…)
。
sequential
将使整个流管道进入顺序模式,因此,传递给forEach
的操作将由同一线程执行,但也由前面的peek
操作执行。对于大多数中间操作来说,parallel
或sequential
的确切位置是不相关的,指定这两种操作没有意义,因为只有最后一种操作才相关。
此外,在使用forEach
时,仍然无法保证订购,即使它在当前的实现中没有任何后果。这在“Stream.forEach是否尊重连续流的相遇顺序”中讨论
流的文档。forEachOrdered
声明:
此操作一次处理一个元素,如果存在,则按相遇顺序处理。对一个元素执行操作发生在对后续元素执行操作之前,但对于任何给定元素,操作可以在库选择的任何线程中执行。
因此,动作可能会被不同的线程调用,这可以被Thread.currentThread()
感知到,但不会同时运行。此外,如果流有遭遇顺序,它将在此处重新构建。这个答案揭示了遭遇顺序和处理顺序的区别。
我偶然发现了一个我无法解决的任务。我不得不修改代码以打印而不是。 我明白为什么要这样印。 我很感激任何帮助。
问题内容: 这个问题已经在这里有了答案 : Java的foreach循环是否保留顺序? (2个答案) 4年前关闭。 java for-each循环是否保证如果在列表上调用这些元素,它们将按顺序显示?在我的测试中,它确实存在,但是我似乎找不到任何文档中明确提及的内容。 问题答案: 是。foreach循环将按方法提供的顺序遍历列表。请参阅Iterable接口的文档。 如果查看List的Javadoc,
问题内容: 我有一个包含博客文章的数据库表。我想在首页上显示每个类别的一则(或更多)帖子,例如按日期排序。 所以我的posts表看起来像这样: 我将如何创建这样的查询?我曾经考虑过使用group-by或subselect,但是我不确定这是否对性能有好处…该表具有大量记录。 问题答案: MySQL 不 支持解析功能(ROW_NUMBER,RANK,DENSE_RANK,NTILE …),但是您可以使
我有一个自定义对象数组。我想循环遍历每个元素,并检查该自定义对象类型为String的特定字段。我想断言等于预期值的值。但是我不能准备这份声明。请帮忙。 我的代码:
问题内容: 您能否解释一下已经在各种servlet实现中实现的两种方法: 每个连接线程 每个请求的线程 以上两种策略中的哪一种可以更好地扩展,为什么? 问题答案: 以上两种策略中的哪一种可以更好地扩展,为什么? 每个请求线程的可伸缩性比每个连接线程的可伸缩性更好。 Java线程非常昂贵,通常每个线程都使用1Mb的内存段,无论它们是活动的还是空闲的。如果为每个连接提供自己的线程,则该线程通常在连接的
问题内容: servlet类有多个实例吗?当我听到“每个servlet实例”时,有人可以详细说明吗? 问题答案: Servlet容器启动时,它: 读; 在类路径中找到已声明的Servlet;和 加载和实例化每个Servlet一次。 大概是这样的: 这些Servlet都存储在内存中,并且每次请求URL与Servlet的关联的匹配时都可以重用url-pattern。然后,Servlet容器执行类似于以