代码之家  ›  专栏  ›  技术社区  ›  yoni

并行流在任务完成之前完成

  •  1
  • yoni  · 技术社区  · 8 年前

    我使用此方法使用默认值初始化ArrayList:

    private ArrayList<Integer> createArrayList(int size, int defaultValue)
    {
        ArrayList<Integer> arrayList = new ArrayList<>(size);
        IntStream.range(0, size ).parallel().forEach(i->{arrayList.add(defaultValue);});
    
        return arrayList;
    }
    

    令人惊讶的是,如果我用单元测试检查返回数组的大小,它不是固定的数字,而且几乎总是小于请求的大小。

    如果我删除 parallel() 其大小始终符合要求。

    为什么会这样?

    2 回复  |  直到 7 年前
        1
  •  10
  •   Eugene    8 年前

    当然 它更小,您正在将多个线程中的多个元素添加到非线程安全的 ArrayList (当元素无法填充其原始大小时,会重新调整大小)。

    您可以通过以下方式更简单地做到这一点:

    Collections.nCopies(i, defaultValue);
    
        2
  •  0
  •   suenda    8 年前

    使用线程安全的CopyOnWriteArrayList而不是ArrayList

    private ArrayList<Integer> createArrayList(int size, int defaultValue)
    {
        List<Integer> list = new CopyOnWriteArrayList<>(size);
        IntStream.range(0, size ).parallel().forEach(i->{list.add(defaultValue);});
    
        return list;
    }