CopyOnWriteArrayList 太慢

CopyOnWriteArrayList is too slow

我有以下案例,

public class Test {

    private static final int MAX_NUMBER = 10_00_00;

    public static void main(String[] args) {
        List<Integer> list = new CopyOnWriteArrayList<>();

        long start = System.nanoTime();
        for(int i = 0; i < MAX_NUMBER; i++) {
            list.add(i * 2);
        } 
        long end = System.nanoTime();
        System.out.println(((end - start) / Math.pow(10, 9)));
    }

}

输出

6.861539857

ArrayList 相比,它添加元素相当 缓慢 ,后者花费了大约 0.004690843。我开始在文档中知道原因,

A thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.

因此,我的理解是,每当我在此列表中添加新元素时,它都会创建新的新数组并在该数组的最后一个索引处添加元素。我在 add 方法中找到了一个锁,除此之外,该方法实际上每次都在创建新数组。

当我将 MAX_NUMBER 增加到 10_00_000 时,我的程序一直在 运行 并且永远不会结束(它会,但我不能等这么久).

我认为 Collections.synchronizedList 是更好的选择,当你想要线程安全和速度。我用了它,花了大约 0.007673728.

我的问题:

  1. 为什么在内部创建新数组线程安全与此有关?
  2. 为什么 MAX_NUMBER = 10_00_000 花了这么多时间? (因为 MAX_NUMBER = 10_00_00 花了大约 6 秒)发生这种情况是因为每次操作都会创建新数组吗?
  3. 这是否意味着当您拥有大量元素并且最好选择其他元素(即 Collections.synchronizedList)时 CopyOnWriteArrayList 存在性能缺陷?
  4. 这就是我们通常在 public API 中看不到 CopyOnWriteArrayList 的原因吗?除此之外还有什么缺点吗?

CopyOnWriteArrayList 是首选选项,仅当写入次数非常少而读取次数非常多时(如果多个线程正在访问此列表)