Parallel Stream 给出空项,如何在 Java 8 中执行
Parallel Stream gives null items, How to do in Java 8
我在尝试使用并行流时得到了一些奇怪的结果,我知道一个解决方法,但它似乎并不理想
// 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一个List
selected
是在此操作期间未修改的 HashSet<Integer>
。
somethingSubGroupDTO.addFilterDTO
是添加到未同步列表的辅助函数。这就是问题。作为一个不同步的列表,我在列表中得到的项目比预期的要少,而且有些项目是空的。如果我把它变成一个同步列表,它就可以工作。显然在并行流中加入锁竞争是不理想的。
在高层次上,我知道可以通过这样一种方式来做到这一点,即每个流都将进行自己的处理,并且当它们加入时它们将聚合。 (至少我可以想象这样一个没有锁争用的过程)但是因为我是 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
对象中,而不是一次添加一项。
我在尝试使用并行流时得到了一些奇怪的结果,我知道一个解决方法,但它似乎并不理想
// 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一个List
selected
是在此操作期间未修改的 HashSet<Integer>
。
somethingSubGroupDTO.addFilterDTO
是添加到未同步列表的辅助函数。这就是问题。作为一个不同步的列表,我在列表中得到的项目比预期的要少,而且有些项目是空的。如果我把它变成一个同步列表,它就可以工作。显然在并行流中加入锁竞争是不理想的。
在高层次上,我知道可以通过这样一种方式来做到这一点,即每个流都将进行自己的处理,并且当它们加入时它们将聚合。 (至少我可以想象这样一个没有锁争用的过程)但是因为我是 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
对象中,而不是一次添加一项。