代码报错ConcurrentModificationException的原因

我们在执行代码的时候,可能会遇到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;
}

所以我们在使用迭代器时要注意当前的集合是否会被修改,并注意异常的处理。