Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel Stream gives null items, How to do in Java 8

I'm getting some weird results when trying to use a parallel stream and I know a workaround, but it doesn't seem ideal

// Create the set "selected"
somethingDao.getSomethingList().parallelStream()
                .filter(something -> !selected.contains(something.getSomethingId()))
                .forEach(something ->
                                somethingSubGroupDTO.addFilterDTO(
                                        new FilterDTO(something.getSomethingName(), something.getSomethingDescription(), false))
                );
selected.clear();

somethingDao.getSomethingList returns a List

selected is a HashSet<Integer> that is not modified during this operation.

somethingSubGroupDTO.addFilterDTO is a helper function that adds to an unsynchronized List. This is the problem. As an unsynchronzed list I get less items in the list than expected AND some items are null. If I turn this into a synchronized list it works. Obviously adding lock contention to a parallel stream is not ideal.

At the high level I know it's possible to do this in such a way that each stream will do its own processing and when they join they will aggregate. (At least I can imagine such a process without lock contention) However since I'm new to Java 8 stream processing I'm not aware of how. How do I do this same operation without having contention at a single point?

like image 406
Carlos Bribiescas Avatar asked Oct 29 '15 14:10

Carlos Bribiescas


1 Answers

Don't use forEach and collect your Stream into a List instead:

somethingDao.getSomethingList().parallelStream()
                .filter(something -> !selected.contains(something.getSomethingId()))
                .map(something -> new FilterDTO(something.getSomethingName(), something.getSomethingDescription(), false))
                .collect(toList());

Then, you can set the returned list directly into your somethingSubGroupDTO object, instead of adding one item at a time.

like image 98
Tunaki Avatar answered Nov 07 '22 04:11

Tunaki