并发修改异常ConcurrentModificationException
产生原因
迭代器遍历过程中,通过集合对象add()方法修改了集合中的元素,使成员变量modCount++(此为实际修改次数)。造成了迭代器获取元素中,判断预期修改次数与实际修改次数不一致----modCount!=expectedModCount而抛出了并发修改异常。
public class List {
public static void main(String[] args) {
//创建集合对象
java.util.List<String> list=new ArrayList<String>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//遍历集合,得到每一元素,看有没有“world”这个元素
Iterator<String> it=list.iterator();
while(it.hasNext()){
String s=it.next();
if(s.equals("world")){
list.add("javaee");
}
}
//输出集合对象
System.out.println(list);
}
}
列如:
第一步:
先在上面代码中如果String s通过equals()方法判断和"world"内容相对,将调用list集合方法add(),成员变量modCount++实际修改的值加一。
add()方法:
public boolean add(E e) {
modCount++;//实际修改的值自增
add(e, elementData, size);
return true;
}
第二步:
while进行循环判断,it.hasNext()返回为true,执行String s=it.next()语句;将调用迭代器的next()方法,通过checkForComodification()判断modCount != expectedModCount抛出并发修改异常;
最开始时迭代器的实现类执行int expectedModCount = modCount;实际修改次数与预期修改次数相等,但在迭代遍历过程中调用了add()方法使的modCounter的值改变。
next()方法:
private class Itr implements Iterator<E> {
int expectedModCount = modCount;
/*
modCount:实际修改的次数
expectedModCount:预期修改的次数
*/
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)//判断实际修改次数与预期修改次数是否不等,若不等则抛出并发修改异常
throw new ConcurrentModificationException();
}
}
解决办法:.不使用迭代器遍历,使用普通for遍历。