解决问题
如何理解CopyOnWrite?
关键词
数组、new数组、复制、数组更新、数组引用更新
code
CopyOnWriteArrayList.set(int index, E element)
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 {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
CopyOnWriteArrayList.iterator()
static final 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;
}
...
}
List<String> sl = new CopyOnWriteArrayList<String>();
sl.add("a");
sl.add("b");
sl.add("c");
/*此处用作遍历的COWIterator中的数组引用 始终都没有被更新过*/
for(String s : sl){
System.out.println(s);
sl.set(1,s+"1");
/*每次更新都会new一个新的数组,然后将CopyOnWriteArrayList中数组的引用指向该数组*/
System.out.println(sl);
}
/*
a
[a, a1, c]
b
[a, b1, c]
c
[a, c1, c]
遍历过程中List内容已经更新,但是依然是 a b c
*/