Java 不明白为什么.stream()可以正常工作,但是.parallelStream()不能

Java 不明白为什么.stream()可以正常工作,但是.parallelStream()不能,java,java-stream,Java,Java Stream,我需要加速我的程序,并尝试将.stream更改为.parallelStream 汽车是汽车对象的列表。我使用每辆车的id创建一个JsonCurrent,然后使用这个JsonCurrent向carList添加一个新元素 当我使用.stream时,它工作得很好,但是使用.parallelStream时它不工作。调试器向我显示,当调用carService.createJson时,JsonCurrent的所有字段都为null cars.parallelStream().forEach(car ->

我需要加速我的程序,并尝试将.stream更改为.parallelStream

汽车是汽车对象的列表。我使用每辆车的id创建一个JsonCurrent,然后使用这个JsonCurrent向carList添加一个新元素

当我使用.stream时,它工作得很好,但是使用.parallelStream时它不工作。调试器向我显示,当调用carService.createJson时,JsonCurrent的所有字段都为null

cars.parallelStream().forEach(car -> {
            JsonCurrent currentLocation = carPositionService.carPosition(car.getId());
            carList.add(carService.createJson(car, calendarWeek, currentWeek, currentLocation));
        });
流动 如果汽车有60个对象,则carList会像预期的那样包含60个对象

.平行流 如果cars有60个对象,则carList包含36个对象。

如果carList引用的列表实现不是线程安全的,则使用并行流填充它是一个坏主意。 如果您将JsonCurrent对象收集到一个列表中,而不是添加到现有列表中,那么应该可以解决您的问题。您可以在第二次添加carList中收集列表的所有元素,例如:

List<JsonCurrent> collected = 
cars.parallelStream().map(car -> carService.createJson(car, calendarWeek, currentWeek, carPositionService.carPosition(car.getId())).collect(toList());     
carList.addAll(collected);
但是请注意,该行为将不同于非并行流:元素插入的顺序可能不同。
最后,关于性能差异,您应该使用JMH或任何专用工具来判断这两种方法之间的真正差异

并行流可用于无状态、关联和非干扰操作,即

1无状态操作:一个元素的状态不影响另一个元素

2非干扰操作:数据源不受影响

3关联运算:结果不受操作数顺序的影响


因此,您的carList必须是线程安全的。

carList是线程安全的吗?这不是一个问题,但您可能正在多个线程中使用非线程安全操作。请记住,使用parallelStream会使大多数代码的性能更差。另请参阅?更详细的讨论。这对我来说很好。谢谢你指出JMH,我要试试。