java ordered list_关于并行处理:Java 8的forEachOrdered()和sequence()方法之间的区别?...
我正在使用Java 8并行流,并且希望以并行流的方式打印元素是某种顺序(例如插入顺序,反向顺序或顺序顺序)。
为此,我尝试了以下代码:
System.out.println("With forEachOrdered:");
listOfIntegers
.parallelStream()
.forEachOrdered(e -> System.out.print(e +""));
System.out.println("");
System.out.println("With Sequential:");
listOfIntegers.parallelStream()
.sequential()
.forEach(e -> System.out.print(e +""));
对于这两者,我得到的输出如下:
With forEachOrdered:
1 2 3 4 5 6 7 8
With Sequential:
1 2 3 4 5 6 7 8
从api文档中,我可以看到:
forEachOrdered -> This is a terminal operation.
和
sequential -> This is an intermediate operation.
所以我的问题是,哪个更好用?
在哪些情况下,应该优先选择另一种?
listOfIntegers.parallelStream().sequential().forEach()创建一个并行的Stream,然后将其转换为顺序的Stream,因此您最好改用listOfIntegers.stream().forEach(),并首先获得顺序的Stream。
listOfIntegers.parallelStream().forEachOrdered(e -> System.out.print(e +""))在并行的Stream上执行操作,但是保证元素将按Stream的遇到顺序被消耗(如果Stream具有定义的遇到顺序)。但是,它可以在多个线程上执行。
我看不到使用listOfIntegers.parallelStream().sequential()的原因。如果要顺序Stream,为什么要先创建平行的Stream?
因为您可能希望并行执行一些繁重的操作,然后对流重新排序以最终输出
@AdrianShum Im不确定在性能方面的效果如何,因为流是惰性评估的。它不会对所有元素并行执行第一个中间步骤,然后继续其余的中间步骤并在顺序流上进行终端操作。仅当到达终端操作时,它才开始对单个元素执行中间操作,直到它们成为终端操作的输入为止。
确实如此。也许这仅对以下情况有用:我正在编写可在提供的流上使用的util,并且即使用户提供了并行的,我也要确保它是顺序的?
@AdrianShum是的,如果您没有自己创建流,并要求它是顺序的,那么sequential()会很好用。
考虑list.parallelStream().sorted().forEachOrdered(…)作为一个实际的例子,它并行执行大量工作,但执行有序的终端操作。
@Holger,但在示例中您没有将流转换回顺序流
究竟。这是.parallelStream(). … .forEachOrdered(…)和.parallelStream(). … sequential().forEach(…)表现出明显差异的操作示例。如您所说,"流是惰性计算的",因此,如果终端操作由于排序约束而阻塞了工作线程,那么除非您具有像sorted()这样的有状态中间操作,否则您不会获得太多的并行性。
您以某种方式提出了一个令人误解的问题,首先您要询问:
.parallelStream()
.forEachOrdered(...)
这将创建一个并行Stream,但是元素将按顺序使用。如果添加这样的map操作:
.map(...)
.parallelStream()
.forEachOrdered(...)
这将使map的操作非常有限(从并行处理的角度来看),因为线程必须等待遇到顺序中的所有其他元素(由forEachOrdered消耗)。这涉及无状态操作。
另一方面,如果您有状态操作,例如:
.parallelStream()
.map()
.sorted()
.// other operations
由于sorted是有状态的,因此并行处理之前的无状态操作将带来更大的好处。发生这种情况是因为sorted必须从Stream中收集所有元素,并且线程不必"按顺序"遇到元素(在forEachOrdered处)。
对于第二个示例:
listOfIntegers.parallelStream()
.sequential()
.forEach(e -> System.out.print(e +""))
您基本上是说先并联然后再关闭。流由终端操作驱动,因此即使您这样做:
.map...
.filter...
.parallel()
.map...
.sequential
这意味着整个流水线将顺序执行,而不是某个部分是并行的而另一部分则是顺序的。您还依赖于这样一个事实,即forEach会保留顺序并且可能会保留它,但可能会在以后的版本中保留它,这是因为您说过您不关心顺序(首先使用forEach ),则将对元素进行内部改组。
流管线可以顺序执行或并行执行。此执行模式是流的属性。使用初始选择的顺序执行或并行执行来创建流。例如,Collection.stream()创建一个顺序流,而Collection.parallelStream()创建一个并行流。可以通过BaseStream.sequential()或BaseStream.parallel()方法修改执行模式的选择。
因此,无需使用:
listOfIntegers.parallelStream().sequential()
您只能使用:
listOfIntegers.stream()
如果创建parallel stream,则流的元素可能由不同的线程处理。 forEach和forEachOrdered之间的区别在于,forEach将允许以任何顺序处理并行流的任何元素,而forEachOrdered将始终按照其在原始流中出现的顺序来处理并行流的元素。当使用parallelStream()和forEachOrdered时,是一个很好的示例,说明了如何利用多个内核并仍保留输出顺序。请注意,forEachOrdered强制以有序的方式迭代流元素。但是,在forEachOrdered之前链接的任何操作仍将并行发生,因为该流是并行流。
Oracle并没有确切记录在管道中多次更改流执行模式时发生的情况。尚不清楚最后更改是否重要,还是可以并行执行在调用parallel()之后调用的操作是否可以并行执行,而在调用sequential()之后调用的操作是否将依次执行。
"没有记录到当您在管道中多次更改流执行模式时发生的确切情况"。我不同意,它在Stream的类文档中清楚地说明了" Stream管道可以顺序执行或并行执行"
@AnlonBurke请通读最后的内容,Oracle并未对此进行记录。
整个管道可以顺序执行,也可以并行执行。恕我直言,这就是Javadoc所说的话。某些部分不可能是parallel,而另一些部分是sequential(实际上,在Stream API最初开发期间曾尝试过一段时间,但由于过于复杂而已被放弃)。我不明白您对此有何疑问。
java ordered list_关于并行处理:Java 8的forEachOrdered()和sequence()方法之间的区别?...相关推荐
- java定义list_我的Java Web之路59 - Java中的泛型
本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 再谈Java中的类型 为什么需要泛型? J ...
- java 方法 函数 区别_Java中的构造函数和方法之间的区别
Java方法一种方法用于探索对象的行为. 我们可以在方法的前面加上访问修饰符. 方法必须具有返回类型,例如void,任何原始类型(int,char,float等),任何Object类型(Integer ...
- java listfiles 使用_Java中list()和listFiles()方法之间的区别
java.io包的名为File的类表示系统中的文件或目录(路径名).为了获得目录中所有现有文件的列表,此类提供了list()和ListFiles()方法. 它们之间的主要区别是该列表()方法返回一个字 ...
- Java中的wait()和sleep()方法之间的区别
Java中的wait()和sleep()方法 (wait() and sleep() methods in Java) First, we will see how wait() method dif ...
- java limit_Java 8 Stream:limit()和skip()之间的区别
小编典典 您在这里拥有两个流管道. 这些流管道分别由一个源,几个中间操作和一个终端操作组成. 但是中间操作是懒惰的.这意味着除非下游工序需要物料,否则什么也不会发生.如果这样做,则中间操作将完成它所需 ...
- java中的for循环里面创建对象和for循环外面创建对象之间的区别
问题描述: 其实就是我在for循环外面场景对象.想着可以节省内存,可是最终返回list的对象都是最后一个对象对应的数据,代码如下: List<SelectSelfTestReportVo.Con ...
- java getmapping(_java - 注释@GetMapping和@RequestMapping(method = RequestMethod.GET)之间的区别...
@RequestMapping(method=RequestMethod.GET)是一个班级 @RequestMapping(method=RequestMethod.GET)是方法级别 随着spri ...
- Java中File的getPath(),getCanonicalPath()和getAbsolutePath()之间的区别
File API在Java中非常重要,因为它使文件系统可以访问Java程序. 尽管Java的文件API丰富,但是使用它们时仍需要了解许多细节. 关于文件路径的常见查询程序员之一是getPath() , ...
- java多核并行计算_谈谈Java任务的并行处理
前言 谈到并行,我们可能最先想到的是线程,多个线程一起运行,来提高我们系统的整体处理速度:为什么使用多个线程就能提高处理速度,因为现在计算机普遍都是多核处理器,我们需要充分利用cpu资源:如果站的更高 ...
最新文章
- List中subList方法抛出异常java.util.ConcurrentModificationException原理分析
- Pytorch中的错误和bug
- 【LeetCode】10. Regular Expression Matching
- c++接口与实现的分离
- Python代码规范
- java中printreader类_java字符流,字符文件输入流FileReader类介绍
- 【建行】龙支付新老用户赚200元详细教程
- 抗击疫情 融云在行动
- 2549. 删除他们! 解题报告
- Day 15 正则表达式
- OpenLayers 3实践与原理探究3-ol3一个完整的例子
- 【PP模块】工艺路线详解(Routing)
- iconfont字体图标线上环境加载偶尔乱码问题
- shapefile格式(援引)
- 【软件测试-实验-7】使用LR进行性能测试
- 市场调查与预测试题库【1】
- 工程力学(5)—平面任意力系简化与平衡
- java设计模式 课后习题参考答案 第 2 章 面向对象设计原则 清华出版社 刘伟
- 如何开发一个标准的云原生应用?
- 新思路计算机二级考试题库软件,新思路等考通二级Visual Basic
热门文章
- oracle 更改实便例名称,大家好,请教在oracle中能否获取update记录 所涉及的字段的名称?如能实现的话,请教相关实现方法。谢谢~...
- 厌倦了 VMware,试试更轻量级的虚拟机!
- 皮一皮:还以为女神的眼睛特别好看...
- Java中的微信支付(1):API V3版本签名详解
- 每日一皮:给老板演示刚做好的功能...
- 面试:从volatile说到i++的线程安全问题
- 这个神器竟然能分分钟将多个 kubeconfig 合并成一个!
- 你还在百度这些代码吗?
- Spring Doc 生成OPEN API 3文档
- 关于程序猿鄙视链,哽咽