今天项目上报了一些bug,通过查看log发现是ConcurrentModificationException,这个错误之前见过,也知道是遍历list时同时修改了list导致的,但是对其中的原理还不是很清楚,正好借今天的机会学习一下里面的机制。
ArrayList里面有一个变量modCount
,专门用来记录该ArrayList被改变了多少次,增删、排序、replace这些改变链表的操作都会导致这个变量自加1
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++; //自加1
}
有些操作会定义一个变量,如上面的sort操作,在真正排序数据之前会定义expectedModCount ,然后在排序操作之后再比较两者是否相等,如果不相等就会抛出ConcurrentModificationException。
另外,使用迭代器也会做如上操作,在ArrayList的迭代器中,也有一个expectedModCount 变量,并且在每一次执行next()方法的时候都会检查expectedModCount是否和ModCount相等,因此在使用迭代器遍历的是否,就不能直接使用remove操作了,下面的例子就会报错:
List<Integ