Java集合源码学习(8)_List接口的实现_CopyOnWriteArrayList

来源:互联网 发布:2016网络流行词经典版 编辑:程序博客网 时间:2024/05/20 14:17

CopyOnWriteArrayList直接实现了List的接口;没有继承自AbstractList;

1:内部实现的数据结构也是基于数组的;

transient final ReentrantLock lock = new ReentrantLock();//private volatile transient Object[] array;//存放数据的数组

2:每一个修改性的操作(比如add()、remove()、set())都不是直接操作数据实际存放的array的,都是先copy一份数据在copy的数组上进行操作,然后再设置array为新的修改过后的数组;因此,该类比较适合遍历查询多余修改操作的List,发送在查找阶段的修改不能在已经创建的迭代器中显示

例如,

public E set(int index, E element) {final ReentrantLock lock = this.lock;//这个锁是不是只能保证同时只有一个线程可以执行set任务?其他的修改性操作呢?lock.lock();try {Object[] elements = getArray();Object oldValue = elements[index];if (oldValue != element) {int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len);newElements[index] = element;setArray(newElements);} else {// Not quite a no-op; ensures volatile write semanticssetArray(elements);}return (E) oldValue;} finally {lock.unlock();}}
3:每一个查找性的操作,都是copy一份当前的array,在copy的数组上进行查找操作,不会受到修改性操作的影响;

public int indexOf(Object o) {<span style="white-space:pre"></span>Object[] elements = getArray();<span style="white-space:pre"></span>return indexOf(o, elements, 0, elements.length);}
private static int indexOf(Object o, Object[] elements, int index, int fence) {if (o == null) {for (int i = index; i < fence; i++)if (elements[i] == null)return i;} else {for (int i = index; i < fence; i++)if (o.equals(elements[i]))return i;}return -1;}

4:listIterator()返回的是一个COWIterator的实例;不支持remove和add的操作,只能查询;每一次listIterator()都是返回一个新的COWIterator,且查询的数组都是创建迭代器时的array,不受其他修改操作的影响;

private static class COWIterator<E> implements ListIterator<E> {/** Snapshot of the array **/private final Object[] snapshot;/** Index of element to be returned by subsequent call to next. */private int cursor;private COWIterator(Object[] elements, int initialCursor) {cursor = initialCursor;snapshot = elements;}public boolean hasNext() {return cursor < snapshot.length;}public boolean hasPrevious() {return cursor > 0;}public E next() {if (!hasNext())throw new NoSuchElementException();return (E) snapshot[cursor++];}public E previous() {if (!hasPrevious())throw new NoSuchElementException();return (E) snapshot[--cursor];}public int nextIndex() {return cursor;}public int previousIndex() {return cursor - 1;}public void remove() {throw new UnsupportedOperationException();}public void set(E e) {throw new UnsupportedOperationException();}public void add(E e) {throw new UnsupportedOperationException();}}


0 0
原创粉丝点击