CopyOnWriteArrayList源码分析
1)读不加锁,写加锁。
2)Copy-On-Write:写时拷贝。
3)保证最终一致性,不保证实时一致性。
4)尽量批量添加(删除):减少Copy、减少GC。
5)适用场景:读多写少。
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { final transient ReentrantLock lock = new ReentrantLock(); private transient volatile Object[] array; final Object[] getArray() { return array; } final void setArray(Object[] a) { array = a; } public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); // 加锁 try { Object[] elements = getArray(); E oldValue = get(elements, index); // 旧值 if (oldValue != element) { // 新旧值不等 int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); // 拷贝array所有元素到新数组(array.length) newElements[index] = element; // 在新数组中设置新值 setArray(newElements); // array指向新数组 } else { // 新旧值相等 setArray(elements); // array指向新数组 } return oldValue; } finally { lock.unlock(); // 释放锁 } } public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); // 加锁 try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); // 拷贝array所有元素到新数组(array.length + 1) newElements[len] = e; // 在新array末尾添加元素 setArray(newElements); // array指向新数组 return true; } finally { lock.unlock(); // 释放锁 } } public E remove(int index) { final ReentrantLock lock = this.lock; lock.lock(); // 加锁 try { Object[] elements = getArray(); int len = elements.length; E oldValue = get(elements, index); int numMoved = len - index - 1; // 计算index后置位的元素个数 if (numMoved == 0) // index后置位不存在元素 setArray(Arrays.copyOf(elements, len - 1)); // 拷贝index前置位所有元素到新数组(array.length - 1) else { // index后置位不存在元素 Object[] newElements = new Object[len - 1]; // 建立新数组(array.length - 1) System.arraycopy(elements, 0, newElements, 0, index); // 拷贝index前置位所有元素到新数组 System.arraycopy(elements, index + 1, newElements, index, numMoved);// 拷贝index后置位所有元素到新数组 setArray(newElements); // array指向新数组 } return oldValue; } finally { lock.unlock(); // 释放锁 } } public boolean addAll(Collection<? extends E> c); // 批量添加 public boolean removeAll(Collection<?> c); // 批量删除 void removeRange(int fromIndex, int toIndex); // 范围删除 ... ... }