内容选自《码出高效》:
通常多线程(单线程也会)情况下,当前线程会维护一个技术比较器,即expectedModCount,记录已经修改的次数,在进入遍历前,会把实时修改次数modCount赋值给expectedModCount,如果两个不相等,则抛出ConcurrentModificationException异常,java.util下所有集合类都是fail-fast的,而concurrent包中的集合类都是fail-safe的。
expectedModcount:这个值在对象被创建的时候就被赋予了一个固定的值modCount。这个值是不变的。也就是说,如果在迭代器遍历元素的时候,如果modCount这个值发生了改变,那么再次遍历时就会抛出异常。
什么时候modCount会发生改变呢?
当我们对集合的元素的个数做出改变的时候,modCount的值就会被改变,如果删除,插入。但修改则不会。
示例代码:
public class SubListFailFast {
public static void main(String[] args) {
List masterList=new ArrayList();
masterList.add("one");
masterList.add("two");
masterList.add("three");
masterList.add("four");
masterList.add("five");
//subList无法序列化,而且它的修改会导致主列表的修改 且主列表的元素个数改动会让其敏感(例如遍历输出抛出ConcurrentModificationException)异常
List branchList=masterList.subList(0,3);
//报异常java.util.ConcurrentModificationException
// masterList.remove(0);
// masterList.add("ten");
// masterList.clear();
//可执行
branchList.clear();
branchList.add("six");
branchList.add("seven");
branchList.remove(0);
for (Object t:branchList){
System.out.println(t);
}
System.out.println("branchList:"+branchList);
System.out.println("masterList:"+masterList);
}
}