1.继承体系
CopyOnWriteArrayList实现了List, RandomAccess, Cloneable, java.io.Serializable等接口。
CopyOnWriteArrayList实现了List,提供了基础的添加、删除、遍历等操作。
CopyOnWriteArrayList实现了RandomAccess,提供了随机访问的能力。
CopyOnWriteArrayList实现了Cloneable,可以被克隆。
CopyOnWriteArrayList实现了Serializable,可以被序列化。
2.源码解析
2.1 属性分析
// 内部锁,用于操作同步
final transient ReentrantLock lock = new ReentrantLock();
// 底层存储数据的结构,一个volatile 修饰的Object数组
private transient volatile Object[] array;
2.2.1:add(E e)
/**
* add 阻塞写,向CopyOnWriteArrayList中添加一个元素
* 1.获取原数组的引用,并新建一个数组,大小为原数组的size+1
* 2.将原数组的数据复制到新数组中
* 3.将新加入元素添加到新数组的末尾
* 4.将array的指针指向新数组,完成添加操作
* @param e
* @return
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
//1.获取原数组的引用,并新建一个数组,大小为原数组的size+1
Object[] elements = getArray();
int len = elements.length;
// 2.将原数组的数据复制到新数组中
Object[] newElements = Arrays.copyOf(elements, len + 1);
// 3.将新加入元素添加到新数组的末尾
newElements[len] = e;
//4.将array的指针指向新数组,完成添加操作
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
2.2.2:set(int index, E element)
/**
* 1.加锁
* 2.获取原数组 索引位置index的旧值
* 3.比较旧值与要设置的新值是否相等
* 3.1 不相等则新建一个数组,作为旧数组的深拷贝,将新数组的index位置辅助赋值为设置的值
* 将array的引用指向新数组
* 3.2 相等则将array的引用继引用旧数组
* 4.返回旧值
* 5.解锁
*/
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
//1.加锁
lock.lock();
try {
// 2.获取原数组 索引位置index的旧值
Object[] elements = getArray();
E oldValue = get(elements, index);
// 3.比较旧值与要设置的新值是否相等
if (oldValue != element) {
// 3.1不相等则新建一个数组,作为旧数组的深拷贝,将新数组的index位置辅助赋值为设置的值
// 将array的引用指向新数组
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
//3.2 相等则将array的引用继引用旧数组
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
//4.返回旧值
return oldValue;
} finally {
//5.解锁
lock.unlock();
}
}