继承关系
CopyOnWriteArrayList是并发包下的集合类
`Iterable`可进行迭代器迭代
`Collection`拥有集合的一般特性和方法
`List`说明底层是数组存储元素
`Cloneable`可以被克隆
`RandomAccess`通过索引可随机访问
CopyOnWriteArrayList底层维护了一个transient volatile Object[] array数组和一个
transient Object lock = new Object()锁,对于所有的读操作是进行无锁化处理,及时返回原始数组中索引的值,可接受并发,对于写操作需要先获取lock的权限,获取到相关的权限之后,Copy一份原始数组进行写操作,并且写完成之后释放lock,并把array的引用指向新的数组,同时 volatile 保证了每个线程在写操作进行复制的数组为最新。对于读操作时进行写并不影响,读是被复制的集合,而不是最新的集合,这就可能导致数据的前后不一致问题,对于写操作,CopyOnWriteArrayList效率较低同时会占用相当一部分内存,所以适合 读多写少的场景。
添加元素
//添加元素的操作
public boolean add(E e) {
//先获取锁获取操作权限
synchronized (lock) {
//获取原始集合
Object[] es = getArray();
//原始集合数组长度+1
int len = es.length;
//创建 len 长度的集合并复制原始集合元素到新集合
es = Arrays.copyOf(es, len + 1);
//添加元素到新集合的最后的位置
es[len] = e;
//设置array的引用为新集合的地址
setArray(es);
//返回成功标志
return true;
}
//释放锁资源
}
修改元素
public E set(int index, E element) {
//先获取锁获取操作权限
synchronized (lock) {
//获取原始集合
Object[] es = getArray();
//获取index角标处的原始值
E oldValue = elementAt(es, index);
//如果原始值和新值相等不做任何操作
if (oldValue != element) {
//不相等进行一份浅拷贝
es = es.clone();
//替换原始元素
es[index] = element;
}
//设置array的引用为新集合的地址
setArray(es);
//返回原始值
return oldValue;
}
//释放锁资源
}
删除元素
public E remove(int index) {
//先获取锁获取操作权限
synchronized (lock) {
//获取原始集合
Object[] es = getArray();
//原始集合的长度
int len = es.length;
//获取原始index的值
E oldValue = elementAt(es, index);
int numMoved = len - index - 1;
Object[] newElements;
//说明移除的是最后一个元素
if (numMoved == 0)
//直接copy len - 1 长度的原始集合
newElements = Arrays.copyOf(es, len - 1);
else {
//不是最后一个元素,创建新数组 长度为len - 1
newElements = new Object[len - 1];
//拷贝0-index元素到新集合
System.arraycopy(es, 0, newElements, 0, index);
//拷贝index + 1 之后的所有元素到新集合
System.arraycopy(es, index + 1, newElements, index, numMoved);
}
//将新引用赋值给array
setArray(newElements);
//返回原始值
return oldValue;
}
//释放锁资源
}