前言
ArrayList是线程不安全的,这点毋庸置疑。因为ArrayList的所有方法既没有加锁,也没有进行额外的线程安全处理。而Vector作为线程安全版的ArrayList,存在感总是比较低。因为无论是add、remove还是get方法都加上了synchronized锁,所以效率低下。
JDK1.5引入的J.U.C包中,又实现了一个线程安全版的ArrayList——CopyOnWriteArrayList。
成员变量
先来看下CopyOnWriteArrayList类的定义和底层数据结构
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = 8673264195747942595L;
/** The lock protecting all mutators */
transient final ReentrantLock lock = new ReentrantLock();
/** The array, accessed only via getArray/setArray. */
// 存储数据的array数组,注意此处是用volatile修饰的
private volatile transient Object[] array;
}
根据定义来看,比ArrayList多了一个ReentrantLock成员变量,存储数据的数组用volatile修饰,其余的并没有多少区别。存储数据的结构依然是数组。
构造方法
/**
* Sets the array.
* 语法糖
*/
final void setArray(Object[] a) {
array = a;
}
/**
* Creates an empty list.
*/
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
/**
* Creates a list holding a copy of the given array.
* 创建一个保存给定数组副本的list(把参数给的数组拷贝给成员变量)
*
* @throws NullPointerException if the specified array is null
* 参数数组为null,抛出NullPointerException
*/
public CopyOnWriteArrayList(E[] toCopyIn) {
setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
}
看完构造方法依然有些疑惑,成员变量和构造方法看起来比ArrayList还要简单,到底是如何保证线程安全的呢。或许add方法会给我们答案。
核心方法
add(E e)
add(E e)方法用于往list尾部添加元素,CopyOnWriteArrayLi