When it comes to stream in Java 8, there are 2 different types of stream operation available. They are sequential stream
and parallel stream
. In this article, we will be discussing about parallel stream in java 8. We will look into different examples of using parallel stream, differences between them, performance improvement with parallel stream and also discuss some aspects of using parallel stream.
What is Parallel Stream
Parallel stream enables parallel computing that involves processing elements concurrently in parallel with each element in a seperate thread. But this does not guarantee high performance and faster execution everytime. It again depends on the number of CPU cores available.
With parallel stream, you can partition the workload of a larger operation on all the available cores of a computer multicore processor and keep them equally busy.
Parallelstream has a much higher overhead compared to a sequential one. Parallel stream should be used only when there is a huge amount of elements to process and there is a performance problem with processing these elements. Also the parallel stream operations should be independent.
Other Interesting Posts Java 8 Lambda Expression Java 8 Stream Operations Java 8 Datetime Conversions Java 9 Modularity Features
Creating Parallel Streams
We can create a parallel stream from an existing stream by using parallel(). Following is an example:
Streamstream = Stream.of("John", "Mike", "Ryan","Donald", "Matthew"); Stream parallelStream = stream.parallel();
Another way to create parallelstream is using parallelStream() method.
StreamparallelStream = Arrays.asList("John", "Mike", "Ryan","Donald", "Matthew").parallelStream();
Parallel Stream Example
Following is an example using parallel stream that counts number of prime numbers between 1 and 50.Stream of numbers is created by a range method and then the stream is converted to parallel stream.
public void count() { final long count = IntStream.range(1, 50) .parallel() .filter(number -> isPrime(number)).count(); System.out.println("Count - " + count); } public boolean isPrime(final int number) { return number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number)).noneMatch( divisor -> number % divisor == 0); }
Output : Count - 15
Serial vs Parallel Stream Processing
If we use serial stream the order is guaranted as below:
Stream.of("John", "Mike", "Ryan","Donald", "Matthew").forEach(System.out::println);
Output:
John Mike Ryan Donald Matthew
Whereas, the order is not guaranted while using parallel stream.
Stream.of("John", "Mike", "Ryan","Donald", "Matthew").parallel().forEach(System.out::println);
Output:
Ryan Mike Matthew John Donald
Calling the method parallel on a sequential stream does not imply any concrete transformation on the stream. Internally, a bolean flag is set to signal whether the operations after the stream to be performed parallely or sequentially.
Perform Check with Parallel Stream Processing
Parallel stream providdes significant performance improvement for larger streams. Following is an example that processes large streams and compares the time difference between processing time of sequential stream and parallel stream.
ParallelStreamPerformanceCheck.javapackage com.devglan; import java.util.ArrayList; import java.util.List; /** * @author only2dhir * */ public class ParallelStreamPerformanceCheck { public static void main(String[] args) { // TODO Auto-generated method stub List<Integer> numList = new ArrayList<Integer>(); for (int i = 0; i < 1000; i++) { numList.add(i); } // Processing sequentially long startTime = System.currentTimeMillis(); numList.stream().forEach(i -> processData(i)); long endTime = System.currentTimeMillis(); double sequentialStreamTimetaken = (endTime - startTime) / 1000; System.out.println("Time required with stream() : " + sequentialStreamTimetaken); // Parallel processing startTime = System.currentTimeMillis(); numList.parallelStream().forEach(i -> processData(i)); endTime = System.currentTimeMillis(); long parallelStreamTimetaken = (endTime - startTime) / 1000; System.out.println("Time required with parallelStream() : " + parallelStreamTimetaken); System.out.println("Differential time : " + (sequentialStreamTimetaken - parallelStreamTimetaken)); } private static void processData(int num) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }Output
Time required with stream() : 11.0 Time required with parallelStream() : 2 Differential time : 9.0
Parallel stream operations such as limit and findFirst that rely on the order of the elements are expensive whereas findAny performs better than findFirst because it isn't constrained to operate in the encounter order.
While using parallel stream, an ArrayList can be split much more efficiently than a LinkedList, because the first can be evenly divided without traversing it.
Conclusion
I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.