-1

我有以下情况,

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

与大约花费的时间相比,它添加元素非常缓慢。我在文档中知道了原因,ArrayList0.004690843

一种线程安全的变体,ArrayList其中所有可变操作(添加、设置等)都是通过制作底层数组的新副本来实现的。

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

当我增加到MAX_NUMBER10_00_000的程序继续运行并且永远不会结束时(它会但我不能等待这么久)。

Collections.synchronizedList当您希望线程安全且速度快时,我认为这是更好的选择。我用了它,它花了大约0.007673728.

我的问题:

  1. 为什么它在内部创建新数组,线程安全与此有关吗?
  2. 为什么要花这么多时间以防万一MAX_NUMBER = 10_00_000?(因为它花了大约 6 秒MAX_NUMBER = 10_00_00)发生这种情况是因为变异操作每次都会创建新数组吗?
  3. CopyOnWriteArrayList当您拥有大量元素并且更好地选择其他东西(即)时,这是否意味着性能下降Collections.synchronizedList
  4. 这就是我们通常CopyOnWriteArrayList在公共 API 中看不到的原因吗?除了这个还有什么缺点吗?
4

1 回答 1

5

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

于 2015-09-09T17:41:21.077 回答