/** * The number of times this list has been <i>structurally modified</i>. * Structural modifications are those that change the size of the * list, or otherwise perturb it in such a fashion that iterations in * progress may yield incorrect results. * * <p>This field is used by the iterator and list iterator implementation * returned by the {@code iterator} and {@code listIterator} methods. * If the value of this field changes unexpectedly, the iterator (or list * iterator) will throw a {@code ConcurrentModificationException} in * response to the {@code next}, {@code remove}, {@code previous}, * {@code set} or {@code add} operations. This provides * <i>fail-fast</i> behavior, rather than non-deterministic behavior in * the face of concurrent modification during iteration. * * <p><b>Use of this field by subclasses is optional.</b> If a subclass * wishes to provide fail-fast iterators (and list iterators), then it * merely has to increment this field in its {@code add(int, E)} and * {@code remove(int)} methods (and any other methods that it overrides * that result in structural modifications to the list). A single call to * {@code add(int, E)} or {@code remove(int)} must add no more than * one to this field, or the iterators (and list iterators) will throw * bogus {@code ConcurrentModificationExceptions}. If an implementation * does not wish to provide fail-fast iterators, this field may be * ignored. * MARK: * 列表結構被修改的次數,在所有會修改列表的方法上都會 modCount++; * 在迭代器中控制並發 */ protected transient int modCount = 0;
在注釋里已經說明了The number of times this list has been
structurally modified. 記錄的是list被修改的次數;This field is used by the iterator and list iterator implementation 由迭代器實現使用。
在迭代時異常修改會拋異常ConcurrentModificationException 並發修改異常,說明在迭代時不能修改list
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Test2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String str = iterator.next(); list.remove(str); } } }
以上代碼執行后拋異常
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at com.design.mode.Test2.main(Test2.java:15)
符合注釋上的說明,既然說是由迭代器使用,那再看看迭代器代碼(刪除了不相干代碼)
/** * 這里可以看出 迭代器是 ArrayList 的一個內部實現類 典型的迭代器模式 */ public Iterator<E> iterator() { return new Itr(); } /** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such // 這里將 modCount 賦值給了 expectedModCount int expectedModCount = modCount; Itr() {} public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { // 若修改后 modCount會變化 會與 expectedModCount 數值不相等 if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
看源碼可以得出獲取迭代器時會將 expectedModCount 賦值為 modCount, 若在使用迭代器迭代期間修改列表則會導致兩者不相等,調用next()時會進行checkForComodification檢查拋異常。說明迭代時不可以進行修改操作。
modCount主要目的就是用來限制用戶在迭代時修改列表,造成數據錯亂