CopyOnWriteArrayList:
+没有初始容量的说法,需要添加元素时长度+1
+涉及添加修改的时候使用ReentrantLock加锁,保证线程安全
+遍历时不能进行删除操作
+迭代使用snapshot快照,没有快速失败过程
//替换
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
//先给容器加上锁,只有一个线程能够修改容器里面的元素
lock.lock();
try {
//获取容器
Object[] elements = getArray();
//获取容器中需要修改的值(旧值,index对应位置上的值)
E oldValue = get(elements, index);
//判断旧值是否和要修改的相等
if (oldValue != element) {
//如果不同,则将旧值改为要修改的值
int len = elements.length;
//复制一个新容器,将容器中的值copy到新容器中
Object[] newElements = Arrays.copyOf(elements, len);
//修改新容器中index对应的元素
newElements[index] = element;
//把旧容器用新容器替换掉
setArray(newElements);
} else {
//如果旧值和要修改的值相等,则不修改
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/
//添加
public boolean add(E e) {
final ReentrantLock lock = this.lock;
//先给容器加上锁,只有一个线程能够修改容器里面的元素
lock.lock();
try {
//获取数组
Object[] elements = getArray();
//定义一个int型的值,等于这个数组的长度
int len = elements.length;
//创建一个新数组,容量为原来的数组容量+1,并copy原来的数组到新数组中
Object[] newElements = Arrays.copyOf(elements, len + 1);
//将新值放到新数组的末端
newElements[len] = e;
//将旧容器的引用指向新容器
setArray(newElements);
//成功后返回一个true
return true;
} finally {
lock.unlock();
}
}
/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/
//删除
public E remove(int index) {
final ReentrantLock lock = this.lock;
//先给容器加上锁,只有一个线程能够修改容器里面的元素
lock.lock();
try {
//获取数组
Object[] elements = getArray();
//定义一个int型的值,等于这个数组的长度
int len = elements.length;
//定义一个老值为index对应位置上的值
E oldValue = get(elements, index);
//定义一个int型的值numMoved,为原数组长度-index-1
int numMoved = len - index - 1;
//如果numMoved等于零,则为原数组最后一个值,直接删除
if (numMoved == 0)
setArray(Arrays.copyOf(elements, len - 1));
else {
//如果numMove不等于零,则
//定义一个新数组,长度为原数组 -1
Object[] newElements = new Object[len - 1];
//把从0到index位置的就数组的值copy到新数组的位置
System.arraycopy(elements, 0, newElements, 0, index);
//把从index+1到微端的置copy到新数组的尾部
System.arraycopy(elements, index + 1, newElements, index,
numMoved);
//得到一个新数组
setArray(newElements);
}
return oldValue;
} finally {
lock.unlock();
}
}