An abstract from JCIP
Iterators for the copy-on-write collections retain a reference to the backing array that was current at the start of iteration, and since this will never change, they need to synchronize only briefly to ensure visibility of the array contents.
The iterators returned by the copy-on-write collections do not throw ConcurrentModificationException and return the elements exactly as they were at the time the iterator was created, regardless of subsequent modifications
Looking at the source code at #CopyOnWriteArrayList.iterator()
956 public Iterator<E> iterator() {
957 return new COWIterator<E>(getArray(), 0); // call to private constructor
958 }
993 private final Object[] snapshot;
994
995 private int cursor;
996
997 private COWIterator(Object[] elements, int initialCursor) {
998 cursor = initialCursor;
999 snapshot = elements;
1000 }
You see that the snapshot
points to the array returned by getArray()
and since the array reference returned is volatile, any change on the reference variable is guaranteed to be reflected. (Making the array reference volatile doesn't makes the elements at each index location volatile)
where the change on the array is done inside-
386 public E More ...set(int index, E element) {
387 final ReentrantLock lock = this.lock;
388 lock.lock();
389 try {
390 Object[] elements = getArray();
391 E oldValue = get(elements, index);
392
393 if (oldValue != element) {
394 int len = elements.length;
395 Object[] newElements = Arrays.copyOf(elements, len);
396 newElements[index] = element;
397 setArray(newElements);
398 } else {
399 // Not quite a no-op; ensures volatile write semantics
400 setArray(elements);
401 }
402 return oldValue;
403 } finally {
404 lock.unlock();
405 }
406 }
i.e setArray(newElements);
as seen in the method.
where getArray()
92 final Object[] More ...getArray() {
93 return array;
94 }
& setArray(...)
final void More ...setArray(Object[] a) {
100 array = a;
101 }
are operations on this volatile array
private volatile transient Object[] array;
Clearly, the iterator is returning the array which (if) has been modified, and not the one created at the start of the iteration process.
So, what does the author mean-
return the elements exactly as they were at the time the iterator was created, regardless of subsequent modifications.