我有以下情况,
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
一种线程安全的变体,
ArrayList
其中所有可变操作(添加、设置等)都是通过制作底层数组的新副本来实现的。
所以,我的理解是,每当我在这个列表中添加新元素时,它都会创建新的新数组并在这个数组的最后一个索引处添加元素。我找到了一个锁定add
方法,除此之外,该方法实际上每次都创建新数组。
当我增加到MAX_NUMBER
我10_00_000
的程序继续运行并且永远不会结束时(它会但我不能等待这么久)。
Collections.synchronizedList
当您希望线程安全且速度快时,我认为这是更好的选择。我用了它,它花了大约0.007673728
.
我的问题:
- 为什么它在内部创建新数组,线程安全与此有关吗?
- 为什么要花这么多时间以防万一
MAX_NUMBER = 10_00_000
?(因为它花了大约 6 秒MAX_NUMBER = 10_00_00
)发生这种情况是因为变异操作每次都会创建新数组吗? CopyOnWriteArrayList
当您拥有大量元素并且更好地选择其他东西(即)时,这是否意味着性能下降Collections.synchronizedList
?- 这就是我们通常
CopyOnWriteArrayList
在公共 API 中看不到的原因吗?除了这个还有什么缺点吗?