异常的产生原因:在迭代器遍历集合的过程中,调用集合自身的功能(例如:调用集合的 add 和 remove 方法),改变集合的长度。
示例:并发修改异常
package com.github.collection1.demo4;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author maxiaoke.com
* @version 1.0
*/
public class Test {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("aa");
collection.add("bb");
collection.add("cc");
collection.add("dd");
for (Iterator<String> iterator = collection.iterator(); iterator.hasNext();) {
String ele = iterator.next();
System.out.println("ele = " + ele);
collection.add("ee");
}
}
}
需要注意的是,迭代器的快速失败机制行文不能得到保证,一般来说,存在不同步的并发修改时,不可能做出任何坚决的保证。快速失败机制尽最大努力抛出 ConcurrentModificationException 。因此,迭代器的快速失败行文应该仅仅用于检测bug 。
快速失败机制的实现原理:
○ ① 在 ArrayList 等集合类中都有一个 modCount 变量,它用来记录集合的结构被修改的次数。
○ ② 当我们给集合添加或删除元素的时候,会导致 modCount++ 。
○ ③ 当我们使用 Iterator 迭代器遍历集合的时候,会使用一个变量记录当前集合的 modCount 。例如:int expectedModCount = modCount;,并且,在迭代器每次 next() 迭代元素的时候,都要检查 expectedModCount != modCount ,如果不相等,则说明调用了 Iterator 迭代器以外的 Collection 的 add 、remove 等方法,修改了集合的结构,使得 modCount++ ,值变了,就会抛出 ConcurrentModificationException 。