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
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