我们在执行代码的时候,可能会遇到ConcurrentModificationException异常,这个异常是怎么产生的呢?
出现ConcurrentModificationException异常,是因为你在使用迭代器Iterator遍历集合,例如list、set时,同时后别的线程对其进行修改,因为Iterator能够检测到容器在生成之后被修改过,为了程序安全抛出ConcurrentModificationException异常,如果不做这样的检查,程序很可能会产生下标越界的异常。
具体分析一下:
集合在使用iterator,调用next()方法时,发现集合被修改,则报错:ConcurrentModificationException
方法:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
所以迭代不加锁,多线程都可以并发读取集合并进行遍历,当然也可以做添加或删除元素,只是修改后,会报错ConcurrentModificationException。
避免ConcurrentModificationException的方法:
1)对迭代器加锁
2)复制容器
另外,集合的containsAll()方法,也会隐式调用itertaor()方法,生成迭代器,使用了迭代器,迭代器中的next方法,也会校验集合是否被修改,也存在报错:ConcurrentModificationException。
例如LinkedList的containsAll()方法源码:
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
所以我们在使用迭代器时要注意当前的集合是否会被修改,并注意异常的处理。