前提,看一下这个
并发异常
代码中的具体逻辑
创建Iterator迭代器的时候,第一步首先对expectedModCount进行赋值int expectedModCount = modCount;接下来调用hasNext方法,看是否有下一个对象,根据当前索引值是否等于迭代器长度进行控制然后调用next()方法,返回list集合迭代器中当前索引值的元素.本方法中第一行代码是checkForComodification();检查模型修改次数是否和期望值相同接下来调用迭代器的remove,add,set方法.在对元素进行修改的时候,对期望的修改次数进行了重新赋值,expectedModCount = modCount;意思就是如果使用迭代器自身的增删改方法,迭代器是会进行重新进行赋值.然后进行下一次迭代的时候,next()方法的第一行检查就会通过.但是如果使用集合本身的方法进行了增删改操作,modCount++,但是迭代器不会对expectedModCount重新进行赋值.进行下一次迭代的时候,进行到next()方法第一行的时候,检查不通过,报错并发修改异常.源码如下 包名java.util.AbstractList
public ListIterator
<E> listIterator(final int index
) {
rangeCheckForAdd(index
);
return new ListItr(index
);
}
private class Itr implements Iterator<E> {
int cursor
= 0;
int lastRet
= -1;
int expectedModCount
= modCount
;
public boolean hasNext() {
return cursor
!= size();
}
public E
next() {
checkForComodification();
try {
int i
= cursor
;
E next
= get(i
);
lastRet
= i
;
cursor
= i
+ 1;
return next
;
} catch (IndexOutOfBoundsException e
) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet
< 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList
.this.remove(lastRet
);
if (lastRet
< cursor
)
cursor
--;
lastRet
= -1;
expectedModCount
= modCount
;
} catch (IndexOutOfBoundsException e
) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount
!= expectedModCount
)
throw new ConcurrentModificationException();
}
}
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index
) {
cursor
= index
;
}
public boolean hasPrevious() {
return cursor
!= 0;
}
public E
previous() {
checkForComodification();
try {
int i
= cursor
- 1;
E previous
= get(i
);
lastRet
= cursor
= i
;
return previous
;
} catch (IndexOutOfBoundsException e
) {
checkForComodification();
throw new NoSuchElementException();
}
}
public int nextIndex() {
return cursor
;
}
public int previousIndex() {
return cursor
-1;
}
public void set(E e
) {
if (lastRet
< 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList
.this.set(lastRet
, e
);
expectedModCount
= modCount
;
} catch (IndexOutOfBoundsException ex
) {
throw new ConcurrentModificationException();
}
}
public void add(E e
) {
checkForComodification();
try {
int i
= cursor
;
AbstractList
.this.add(i
, e
);
lastRet
= -1;
cursor
= i
+ 1;
expectedModCount
= modCount
;
} catch (IndexOutOfBoundsException ex
) {
throw new ConcurrentModificationException();
}
}
}