/**
* 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主要目的就是用来限制用户在迭代时修改列表,造成数据错乱