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
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.
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.
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.
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.
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())
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With