并行流将项目添加到同一数组

Rob*_*ert 5 java java-stream

我有一个对象数组,我流式传输以在每个对象上使用一个函数来修改它并将其添加到一个全新的对象数组中。

通过使用,.parallel()执行时间加快了 2 倍,但是NullPointerException在循环新数组时我得到了一些 s 。

我尝试调试了几次,但没有成功。看来这个问题只发生在运行时。我尝试实现一个同步函数来将新对象添加到列表中,但遗憾的是它效果不佳。

谁能给我一个建议如何让它发挥作用?提前致谢!

这是代码片段:

private static final Object sync = new Object();
private ArrayList<Object> newList = new ArrayList<Object>();      

private void addNewObject(Object newObject) {
        synchronized (sync) {
            newList.add(newObject);
        }
    }

private Object mutateObject(Object oldObject) {
    // Do something with the object here
    return mutatedObject;
}

public ArrayList<Object> createNewList(ArrayList<Object> oldList) {
    oldList.stream().parallel().forEach(object -> addNewObject(mutateObject(object)));
    return newList;
}
Run Code Online (Sandbox Code Playgroud)

Szy*_*iak 5

考虑将createNewList方法重构为如下所示:

public List<Object> createNewList(List<Object> oldList) {
    return oldList.parallelStream()
            .map(this::mutateObject)
            .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

如果您查看java.util.stream.Stream JavaDoc,您可以看到有一些终端操作,例如forEachcollecttoArray等。在您的问题中,最好使用collect终端操作,因为它在内部处理同步,避免竞争条件情况下,无需进一步实施同步。

.map()使用( 的中间操作)映射对象Stream并将结果并行收集到最终列表可以解决此问题。

函数addNewObjectsync对象应该被删除,因为它不再被使用。

  • 您可以将 `object -&gt; mutateObject(object)` 替换为 `this::mutateObject`。 (2认同)