简体   繁体   中英

Size of ArrayList modified by parallel stream

List<Integer> data = new ArrayList<>();
IntStream.range(0,100).parallel().forEach(data::add);
System.out.println(data.size());

Why above code does not always print 100? What happens to these numbers that are not counted when printed result is for example 94? I know that I can use forEachOrdered(), CopyOnWriteArrayList or Collections.synchronizedList(). But what exactly happens with missing 6 elements in the above example? Does each thread have its own copy of ArrayList and then these are somehow combined?

Because ArrayList is not thread safe.

When two thread try to increment that counter simultaneously, one of them overwrite result of other.

Try to do it with threadsafe collection an you will be fine.

ArrayList<E> is not synchronized / thread-safe, that's why.

You can use synchronized list, as:

List<Integer> data = Collections.synchronizedList(new ArrayList<>());
IntStream.range(0,100).parallel().forEach(data::add);
System.out.println(data.size());

or forEachOrdered , as:

List<Integer> data = new ArrayList<>();
IntStream.range(0,100).parallel().forEachOrdered(data::add);
System.out.println(data.size());

as it's documentations says, that:

the action may be performed in whatever thread the library chooses.

For example you can use synchronizedCollection(). This will help you about that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM