2

I got a requirement to run a collection using parallel stream and it is always running in sequence, here in the below example List is always running in sequence where as IntStream is running in parallel. could some please help me to understand the difference between running a parallel Stream on IntStream and parallel Stream on List<String>.

Also, can you help with the code snippet how to run List<String> in parallel similar to how IntStream is running parallel?

import java.util.List;
import java.util.stream.IntStream;

public class ParallelCollectionTest {

    public static void main(String[] args) {

        System.out.println("Parallel int stream testing.. ");
        IntStream range2 = IntStream.rangeClosed(1, 5);
        range2.parallel().peek(t -> {
            System.out.println("before");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).forEachOrdered(System.out::println);

        System.out.println("Parallel String collection testing.. ");
        List<String> list = List.of("a","b","c","d");
        list.stream().parallel().forEachOrdered(o ->
                {
                    System.out.println("before");
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(o);
                });
    }

}

output of the above code is below.

Parallel int stream testing.. 
before
before
before
before
before
1
2
3
4
5
Parallel String collection testing.. 
before
a
before
b
before
c
before
d

2
  • So you're saying this code is taking about 51 seconds to complete, with 50 seconds being spent on the second part? Commented Jun 29, 2021 at 11:43
  • 1
    no, I mean to say that IntStream processed elements in parallel as you see "before" is printed for multiple elements and it wait for the give sleep time and then printed the elements(1,2,3,4,5), but in case of List of Strings it printed "before" and waited until the sleep time and then printed the element "a", and it repeated those steps for each element(b,c,d) in seq. Commented Jun 29, 2021 at 11:53

1 Answer 1

3

The different behavior is not caused by the different streams (IntStream vs. Stream<String>).

The logic of your two stream pipelines is not the same.

In the IntStream snippet you are performing the sleep in the peek() call, which allows it to run in parallel for different elements, which is why that pipeline ends quickly.

In the Stream<String> snippet you are performing the sleep in the forEachOrdered, which means the sleep() for each element must be performed after the sleep() of the previous element ends. That's the behavior of forEachOrdered - This operation processes the elements one at a time, in encounterorder if one exists.

You can make the second snippet behave similar to the first if you add a peek() call to it:

System.out.println("Parallel String collection testing.. ");
List<String> list = List.of("a","b","c","d","e","f","g","h");
list.stream().parallel().peek(t -> {
    System.out.println("before");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
})
.forEachOrdered(System.out::println);

Now it will produce:

Parallel String collection testing.. 
before
before
before
before
a
b
c
d
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.