CopyOnWriteArrayList太慢了

时间:2015-09-09 17:36:54

标签: java performance thread-safety copyonwritearraylist

我有以下案例,

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相比,它将慢慢地添加 <{1}}。我在文档中了解了原因,

  

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

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

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

我认为10_00_000是您希望线程安全加速的更好选择。我使用了它,大概花了Collections.synchronizedList

我的问题:

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

1 个答案:

答案 0 :(得分:2)

CopyOnWriteArrayList是首选选项,只有少量写入和大量读取(如果多个线程正在访问此列表)