尝试使用并行流时,我得到一些奇怪的结果,我知道一种解决方法,但这似乎并不理想

// 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返回一个Listselected是在此操作期间未修改的HashSet<Integer>
somethingSubGroupDTO.addFilterDTO是一个辅助函数,它添加到未同步的列表中。这就是问题。作为一个未同步的列表,我在列表中获得的项目少于预期的数量,并且某些项目为null。如果我将其转换为同步列表,它将起作用。显然,将锁争用添加到并行流并不理想。

从高层次上讲,我知道这样做的可能性是,每个流都将进行自己的处理,并且当它们加入时将聚合。 (至少我可以想象没有锁争用的这种过程)但是,由于我是Java 8流处理的新手,所以我不知道该怎么做。如何在不争用的情况下执行相同的操作?

最佳答案

不要使用forEach而是将您的流收集到List中:

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

然后,您可以将返回的列表直接设置到somethingSubGroupDTO对象中,而不是一次添加一项。

10-07 15:54