优点:
缺点:
代码示例:
@Test public void testCopyOnWriteArrayList() throws InterruptedException { List<Integer> list = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList()); CopyOnWriteArrayList cowList = new CopyOnWriteArrayList(list); new Thread(() -> { try { TimeUnit.SECONDS.sleep(2); System.out.println("添加的元素:" + (21)); cowList.add(21); } catch (InterruptedException e) { e.printStackTrace(); } }, "t1").start(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(1); System.out.println("添加的元素:" + (22)); cowList.add(22); } catch (InterruptedException e) { e.printStackTrace(); } }, "t2").start(); for (int i = 0, size = cowList.size(); i < size; i++) { System.out.println("cowListSize:" + (size = cowList.size())); System.out.println("value:" + cowList.get(i)); TimeUnit.MILLISECONDS.sleep(500); } TimeUnit.SECONDS.sleep(10); /** * 执行的结果: * * cowListSize:20 * value:1 * cowListSize:20 * value:2 * 添加的元素:22 * cowListSize:21 * value:3 * cowListSize:21 * value:4 * 添加的元素:21 * cowListSize:22 * value:5 * cowListSize:22 * value:6 * cowListSize:22 * value:7 * cowListSize:22 * value:8 * cowListSize:22 * value:9 * cowListSize:22 * value:10 * cowListSize:22 * value:11 * cowListSize:22 * value:12 * cowListSize:22 * value:13 * cowListSize:22 * value:14 * cowListSize:22 * value:15 * cowListSize:22 * value:16 * cowListSize:22 * value:17 * cowListSize:22 * value:18 * cowListSize:22 * value:19 * cowListSize:22 * value:20 * cowListSize:22 * value:22 * cowListSize:22 * value:21 */ }
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; /** The lock protecting all mutators */ final transient ReentrantLock lock = new ReentrantLock(); // 数组 /** The array, accessed only via getArray/setArray. */ private transient volatile Object[] array; final Object[] getArray() { return array; } final void setArray(Object[] a) { array = a; } // 默认构造器,初始化一个空的数组 public CopyOnWriteArrayList() { setArray(new Object[0]); } public CopyOnWriteArrayList(Collection<? extends E> c) { Object[] elements; if (c.getClass() == CopyOnWriteArrayList.class) elements = ((CopyOnWriteArrayList<?>)c).getArray(); else { elements = c.toArray(); // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elements.getClass() != Object[].class) elements = Arrays.copyOf(elements, elements.length, Object[].class); } setArray(elements); } }
public int size() { // 默认是空数组,不为 null return getArray().length; }
public boolean isEmpty() { return size() == 0; }
private static boolean eq(Object o1, Object o2) { return (o1 == null) ? o2 == null : o1.equals(o2); }
private static int indexOf(Object o, Object[] elements, int index, int fence) { // 如果 o 是 null,则在数组 [index, fence) 区间中找出第一个为 null 的元素的位置 if (o == null) { for (int i = index; i < fence; i++) if (elements[i] == null) return i; } else { // o 不为 null,则遍历找出 o 在数组中的位置 for (int i = index; i < fence; i++) if (o.equals(elements[i])) return i; } // 元素 o 在数组中不存在,返回 -1 return -1; }
// 从 index 位置开始向前找等于 o 的元素位置 private static int lastIndexOf(Object o, Object[] elements, int index) { if (o == null) { for (int i = index; i >= 0; i--) if (elements[i] == null) return i; } else { for (int i = index; i >= 0; i--) if (o.equals(elements[i])) return i; } return -1; }
public boolean contains(Object o) { Object[] elements = getArray(); return indexOf(o, elements, 0, elements.length) >= 0; }
public int indexOf(Object o) { Object[] elements = getArray(); return indexOf(o, elements, 0, elements.length); }
public int indexOf(E e, int index) { Object[] elements = getArray(); return indexOf(e, elements, index, elements.length); }
public int lastIndexOf(Object o) { Object[] elements = getArray(); return lastIndexOf(o, elements, elements.length - 1); }
public Object clone() { try { @SuppressWarnings("unchecked") CopyOnWriteArrayList<E> clone = (CopyOnWriteArrayList<E>) super.clone(); clone.resetLock(); return clone; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } }
public Object[] toArray() { Object[] elements = getArray(); return Arrays.copyOf(elements, elements.length); }
private E get(Object[] a, int index) { return (E) a[index]; }
public E get(int index) { return get(getArray(), index); }
// 修改数组元素值,加锁,每次只有一个线程复制数组修改元素的值 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); newElements[index] = element; setArray(newElements); } else { // 保证 volatile 写语义 // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } /** JDK 11 中,源码变化如下: public E set(int index, E element) { synchronized (lock) { Object[] es = getArray(); E oldValue = elementAt(es, index); if (oldValue != element) { es = es.clone(); es[index] = element; } // Ensure volatile write semantics even when oldvalue == element setArray(es); return oldValue; } } */ }
// 添加元素 // 先复制一个数组(Arrays.copyOf) // 再添加元素 // 覆盖旧数组(setArray) 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); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } /** JDK 11 中,源码变化如下: public boolean add(E e) { synchronized (lock) { Object[] es = getArray(); int len = es.length; es = Arrays.copyOf(es, len + 1); es[len] = e; setArray(es); return true; } } */ }
public void add(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; if (index > len || index < 0) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len); Object[] newElements; int numMoved = len - index; if (numMoved == 0) newElements = Arrays.copyOf(elements, len + 1); else { newElements = new Object[len + 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index, newElements, index + 1, numMoved); } newElements[index] = element; setArray(newElements); } finally { lock.unlock(); } }
// 移除元素 // 将原数组移除指定元素,再复制一个新的数组(Arrays.copyOf) // 覆盖旧数组(setArray) 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; if (numMoved == 0) setArray(Arrays.copyOf(elements, len - 1)); else { Object[] newElements = new Object[len - 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index + 1, newElements, index, numMoved); setArray(newElements); } return oldValue; } finally { lock.unlock(); } }
public Iterator<E> iterator() { return new COWIterator<E>(getArray(), 0); } // 迭代器类 static final class COWIterator<E> implements ListIterator<E> { // 数组 private final Object[] snapshot; // 当前遍历的数组下标 private int cursor; private COWIterator(Object[] elements, int initialCursor) { cursor = initialCursor; snapshot = elements; } // 是否还有元素可迭代 public boolean hasNext() { // 如果当前遍历的数组下标小于数组长度,则表示还可以继续迭代 return cursor < snapshot.length; } // 当前遍历的数组下标 cursor 前是否已经遍历过元素 public boolean hasPrevious() { return cursor > 0; } // 获取当前数组下标 cursor 上的元素 @SuppressWarnings("unchecked") public E next() { if (! hasNext()) throw new NoSuchElementException(); return (E) snapshot[cursor++]; } @SuppressWarnings("unchecked") public E previous() { if (! hasPrevious()) throw new NoSuchElementException(); return (E) snapshot[--cursor]; } public int nextIndex() { return cursor; } public int previousIndex() { return cursor-1; } /** * Not supported. Always throws UnsupportedOperationException. * @throws UnsupportedOperationException always; {@code remove} * is not supported by this iterator. */ public void remove() { throw new UnsupportedOperationException(); } /** * Not supported. Always throws UnsupportedOperationException. * @throws UnsupportedOperationException always; {@code set} * is not supported by this iterator. */ public void set(E e) { throw new UnsupportedOperationException(); } /** * Not supported. Always throws UnsupportedOperationException. * @throws UnsupportedOperationException always; {@code add} * is not supported by this iterator. */ public void add(E e) { throw new UnsupportedOperationException(); } @Override public void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); Object[] elements = snapshot; final int size = elements.length; for (int i = cursor; i < size; i++) { @SuppressWarnings("unchecked") E e = (E) elements[i]; action.accept(e); } cursor = size; } }