Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is list.parallelStream().forEach() not processing all the elements in the list in Java?

The following code is not putting all the elements in the destination list after finishing parallel process. Is there any reason for this?

public static void main(String[] args) {

    List<Integer> source =new ArrayList<>();
    List<Integer> destination = new ArrayList<>();
    IntStream.range(0, 10000).forEach(element ->{
        source.add(element);
    });

    //System.out.println(source.size());

    source.parallelStream().forEach(c->{
        destination.add(c);
    });

    System.out.println("Source Size:"+source.size());
    System.out.println("destination size:"+destination.size());
}

Output: Source Size:10000 destination size:4343

like image 291
Prabhu Kvn Avatar asked Feb 06 '20 12:02

Prabhu Kvn


People also ask

When should you not use Parallelstream?

Similarly, don't use parallel if the stream is ordered and has much more elements than you want to process, e.g. This may run much longer because the parallel threads may work on plenty of number ranges instead of the crucial one 0-100, causing this to take very long time.

What is the difference between stream () and Parallelstream ()?

A sequential stream is executed in a single thread running on one CPU core. The elements in the stream are processed sequentially in a single pass by the stream operations that are executed in the same thread. A parallel stream is executed by different threads, running on multiple CPU cores in a computer.

What is Parallelstream in Java?

Java Parallel Streams is a feature of Java 8 and higher, meant for utilizing multiple cores of the processor. Normally any java code has one stream of processing, where it is executed sequentially.

Can we pass a custom thread executor while calling the Parallelstream () method on a collection?

3. Custom Thread Pool. We can actually pass a custom ThreadPool when processing the stream. We used the ForkJoinPool constructor with a parallelism level of 4.


2 Answers

Because ArrayList is not a thread-safe collection. Using a thread-safe collection like CopyOnWriteArrayList would make it correct but not necessarily efficient.

Using a Collector instead would be much simpler and correct. e.g.

source.parallelStream().collect(Collectors.toList())
like image 65
Sleiman Jneidi Avatar answered Sep 28 '22 16:09

Sleiman Jneidi


The forEach operation of the parallel stream is adding elements to an un-synchronized Collection (an ArrayList) from multiple threads. Therefore, the operation is not thread safe, and has unexpected results.

Using forEachOrdered() instead of forEach() will ensure all the elements of the source List are added to the destination List.

However, as mentioned in the other answer, using collect(Collectors.toList()) is the correct way to produce an output List from a Stream.

like image 44
Eran Avatar answered Sep 28 '22 16:09

Eran