尝试使用并行流时,我得到一些奇怪的结果,我知道一种解决方法,但这似乎并不理想
// 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
返回一个List
selected
是在此操作期间未修改的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
对象中,而不是一次添加一项。