Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并行运算符如何更改后续流元素上的流?_Java_Java Stream - Fatal编程技术网

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是平行的吗?假的

现在,当你调用一个终端操作符,比如“代码>前缀或Suth”,即使在中间调用并行,它也只考虑处理过程中的顺序流。如文档所述,最新应用的模式用于整个管道

这有什么用?

你可以问。有可能通过终端操作员“断开”管道来改变管道中部的行为。举个例子,如果我们在第一个<代码> map 之后应用<代码>收集/代码>,第一个<代码> map <代码>将被顺序执行,然后并行将只适用于后续的运算符,但实际上,这是一个不同的流水线,因为所有的东西都被收集到中间。
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,我的问题更多的是影响管道的并行操作,而不是并行本身。答案已经给出了。整个流管道可以是顺序的,也可以是并行的。没有借口。