Java – stream and parallelstream

I have a test code like this:

List<Integer> list = new ArrayList<>(1000000);

for(int i=0;i<1000000;i++){
    list.add(i);
}

List<String> values = new ArrayList<>(1000000);

list.stream().forEach(
    i->values.add(new Date().toString())
);

System.out.println(values.size());

Running this, I got a correct output: 1000000

However, if I change stream () to parallelstream (), it is as follows:

list.parallelStream().forEach(
    i->values.add(new Date().toString())
 );

I have a random output, for example: 920821

What's up?

Solution

ArrayList is not synchronized An attempt to add an element to it at the same time is not defined From foreach:

In the second example, you will eventually call add multiple threads on the array list at the same time, and the ArrayList document says:

Wrong solution

If you change the use of ArrayList to vector, you will get the correct results because the list implementation is synchronized Its Javadoc says:

But do not use it! In addition, it may eventually slow down due to explicit synchronization

Correct method

Obviously, this is to avoid the situation that the stream API uses the collect method to provide mutable reduction examples following

List<String> values = list.stream().map(i -> "foo").collect(Collectors.toList());

The correct results will always be provided whether running in parallel or not The stream pipeline handles concurrency and guarantees that it is safe to use a non concurrent collector in a collect operation of a parallel stream Collectors. Tolist () is a built - in collector that accumulates stream elements into a list

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>