Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Stream API - Parallel and Sequential Streams

Tags:

java

I am new to the Stream API.I have a question about Stream API,specifically the parallel and sequential stream. The question is:if,for example,i have a pseudo-code like this:

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

Is the Stream API going to execute filter in parallel and mapping sequentially,or does it merely change the "parallel-characteristic" of the stream,so,in this example,the stream is going to be sequential?

like image 831
Barracuda Avatar asked Jul 27 '20 09:07

Barracuda


2 Answers

The calls to sequential() and parallel() simply change the mode of the entire stream. Whichever mode the stream is in when a terminal operation is invoked is the mode used. In your case, since sequential() is after parellel() your stream will be executed sequentially.

This is documented by the Stream interface:

Stream pipelines may execute either sequentially or in parallel. This execution mode is a property of the stream [emphasis added]. Streams are created with an initial choice of sequential or parallel execution. (For example, Collection.stream() creates a sequential stream, and Collection.parallelStream() creates a parallel one.) This choice of execution mode may be modified by the BaseStream.sequential() or BaseStream.parallel() methods, and may be queried with the BaseStream.isParallel() method.

And the java.util.stream package:

The stream pipeline is executed sequentially or in parallel depending on the mode of the stream on which the terminal operation is invoked. The sequential or parallel mode of a stream can be determined with the BaseStream.isParallel() method, and the stream's mode can be modified with the BaseStream.sequential() and BaseStream.parallel() operations. The most recent sequential or parallel mode setting applies to the execution of the entire stream pipeline [emphasis added].

like image 89
Slaw Avatar answered Oct 19 '22 03:10

Slaw


The quickest way to get an answer to such question is to create a very simple test. I've tried something like so:

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));
}

When you run the code and analyse the output of both of those streams you can see that the first one was parallel and the second one was sequential.

Based on that we can deduce that only the last parallel/sequential call matters - it is basicly overwriting the flag.

like image 2
Amongalen Avatar answered Oct 19 '22 05:10

Amongalen