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?
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.
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