Java Stream API - 并行和顺序流

8

我是新手对于Stream API的理解还有问题,具体来说就是关于parallel和sequential stream。我的问题如下:比如,我有这样一段伪代码:

someStream
    .parallel()
    .filter(some_predicate)
    .sequential()
    .map(some_mapping_function)
    .terminal_operation();

Stream API是否会并行执行过滤操作而顺序执行映射操作,还是仅仅改变流的“并行特性”,因此在这个例子中,该流将变为顺序执行?

2个回答

6
调用sequential()parallel()方法只是改变了整个流的模式。在调用终端操作时,无论流处于哪种模式下,都将使用该模式。在您的情况下,由于parallel()sequential()之后,所以流将按顺序执行。这在Stream接口中有说明:

流管道可以顺序执行或并行执行。 此执行模式是流的属性 [强调添加]。流被创建时初始选择连续或并行执行。 (例如,Collection.stream()创建一个顺序流,而Collection.parallelStream()创建一个并行流)。这种执行模式的选择可以通过BaseStream.sequential()BaseStream.parallel()方法进行修改,并且可以使用BaseStream.isParallel()方法查询。

java.util.stream包中也有说明:

流管道根据调用终端操作时流的模式来顺序执行或并行执行。使用BaseStream.isParallel()方法可以确定流是顺序执行还是并行执行,并且可以使用BaseStream.sequential()BaseStream.parallel()操作修改流的模式。 最近的连续或并行模式设置适用于整个流管道的执行 [强调添加]


2
回答如下:

要快速得到这样问题的答案,最简单的方法是创建一个非常简单的测试。我尝试过类似于以下方式:

public static void main(String args[]) {
    List<Integer> list = new ArrayList<>();
    for (int i=0; i<50;i++){
        list.add(i);
    }

    list.stream()
        .sequential()
        .map(a->{
            System.out.println("sequential " + a); 
            return a;
        })
        .parallel()
        .forEach(a-> System.out.println("parallel " + a));
    
    System.out.println();
    System.out.println();
    
    list.stream()
        .parallel()
        .map(a->{
            System.out.println("parallel " + a); 
            return a;
        })
        .sequential()
        .forEach(a-> System.out.println("sequential " + a));
}

当您运行代码并分析这两个流的输出时,您会发现第一个是并行的,而第二个是顺序的。
基于此,我们可以推断出只有最后一个parallel/sequential调用是重要的 - 它基本上覆盖了标志。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接