Java 并行运算符如何更改后续流元素上的流?
执行代码如下Java 并行运算符如何更改后续流元素上的流?,java,java-stream,Java,Java Stream,执行代码如下 List.of(1, 2, 3, 4).stream() .map( integer -> { System.out.println( "Before parallel operator : " + Thread.currentThread().getName() + " : " + integer); return integer * 2; }) .paral
List.of(1, 2, 3, 4).stream()
.map(
integer -> {
System.out.println(
"Before parallel operator : " + Thread.currentThread().getName() + " : " + integer);
return integer * 2;
})
.parallel()
.map(
integer -> {
System.out.println(
" After parallel operator : " + Thread.currentThread().getName() + " : " + integer);
return integer * 2;
})
.forEach(
integer -> {
System.out.println(" For Each : " + Thread.currentThread().getName() + " : " + integer);
});
输出:
Before parallel operator : main : 3
Before parallel operator : ForkJoinPool.commonPool-worker-19 : 2
Before parallel operator : ForkJoinPool.commonPool-worker-23 : 1
Before parallel operator : ForkJoinPool.commonPool-worker-5 : 4
After parallel operator : main : 6
After parallel operator : ForkJoinPool.commonPool-worker-23 : 2
After parallel operator : ForkJoinPool.commonPool-worker-19 : 4
After parallel operator : ForkJoinPool.commonPool-worker-5 : 8
For Each : ForkJoinPool.commonPool-worker-19 : 8
For Each : main : 12
For Each : ForkJoinPool.commonPool-worker-23 : 4
For Each : ForkJoinPool.commonPool-worker-5 : 16
除了元素3之外,所有其他元素还是并行运行?
想了解并行运算符在后续调用中的行为吗
并行操作符从何处开始,并行如何继续?在调用终端操作(例如
forEach
或collect
)之前,流不会被处理,更详细地说。那么,回答你的问题,“并行操作符在哪里启动,并行如何继续?”
医生怎么说?
对于这件事,政府很清楚:
可以使用BaseStream.sequential()和BaseStream.parallel()操作修改流的模式。最新的顺序或并行模式设置应用于整个流管道的执行
一点演示
现在考虑下面的代码(请原谅我的代码>系统.out < /COD>,这是为了演示目的)。如果在
parallel
和sequential
之间切换,则整个管道都会发生变化,而不仅仅是后续的操作符
System.out.println(“==将流s1创建为1,2,3,4”);
var s1=List.of(1,2,3,4).stream();
System.out.println(“s1是平行的?”+s1.isParallel());
System.out.println(“==s2将映射应用于s1的结果”);
var s2=s1.map(整数->整数*2);
System.out.println(“s1是平行的?”+s1.isParallel());
System.out.println(“s2是平行的?”+s2.isParallel());
System.out.println(“==s3应用并行于s2的结果”);
var s3=s2.parallel();
System.out.println(“s1是平行的?”+s1.isParallel());
System.out.println(“s2是平行的?”+s2.isParallel());
System.out.println(“s3是并行的?”+s3.isParallel());
System.out.println(“==将map应用于s3的s4结果”);
var s4=s3.map(整数->整数*2);
System.out.println(“s1是平行的?”+s1.isParallel());
System.out.println(“s2是平行的?”+s2.isParallel());
System.out.println(“s3是并行的?”+s3.isParallel());
System.out.println(“s4是平行的?”+s4.isParallel());
System.out.println(“==将顺序应用于s4的s5结果”);
var s5=s4.顺序();
System.out.println(“s1是平行的?”+s1.isParallel());
System.out.println(“s2是平行的?”+s2.isParallel());
System.out.println(“s3是并行的?”+s3.isParallel());
System.out.println(“s4是平行的?”+s4.isParallel());
System.out.println(“s5平行?”+s5.isParallel());
这将输出以下内容:
==将流s1创建为1,2,3,4
s1是平行的吗?假的
==s2将映射应用于s1的结果
s1是平行的吗?假的
s2是平行的吗?假的
==s3平行于s2的应用结果
s1是平行的吗?真的
s2是平行的吗?真的
s3是并行的吗?真的
==s4将map应用于s3的结果
s1是平行的吗?真的
s2是平行的吗?真的
s3是并行的吗?真的
s4是平行的吗?真的
===s5对s4施加顺序压力的结果
s1是平行的吗?假的
s2是平行的吗?假的
s3是并行的吗?假的
s4是平行的吗?假的
s5是平行的吗?假的
现在,当你调用一个终端操作符,比如“代码>前缀或
List.of(1,2,3,4).stream()
.map(整数->{
System.out.println(“流前:“+Thread.currentThread().getName()+”:“+integer”);
返回整数*2;
})
.collect(收集器.toList())
.stream()
.parallel()
.map(整数->{
System.out.println(“在并行流之后:“+Thread.currentThread().getName()+”:“+integer”);
返回整数*2;
})
.forEach(integer->System.out.println(“For Each:+Thread.currentThread().getName()+”:“+integer”);
现在将输出如下内容:
流之前:主:1
流前:干管:2
流前:干管:3
流前:干管:4
平行流后:干管:6
并行流之后:ForkJoinPool.commonPool-worker-23:2
并行流之后:ForkJoinPool.commonPool-worker-5:4
并行流之后:ForkJoinPool.commonPool-worker-19:8
每个:ForkJoinPool.commonPool-worker-19:16
每个:ForkJoinPool.commonPool-worker-5:8
每个:ForkJoinPool.commonPool-worker-23:4
各:主:12
请注意,第一个映射是如何顺序执行的,而其余的操作符是如何并行执行的
Observable streams实现,例如,使用observeOn
操作符获得了不同的窍门,但它们也是一种完全不同的操作方式。您的输出与print语句中的文本不匹配。此外,名为main
的线程与名为…commonPool worker…
的其他线程并行运行,因此元素3与任何其他元素一样并行运行。您有四个元素由四个不同的线程处理。更多的并行是不可能的。@Holger,我的问题更多的是影响管道的并行操作,而不是并行本身。答案已经给出了。整个流管道可以是顺序的,也可以是并行的。没有借口。