已经有很多帖子分析了Fast-fail机制,就不累述了。
往往我们喜欢把知识点提炼成最精简的话语放到大脑里,就是
Fast-fail机制是为了防止迭代器进行集合迭代过程中对集合元素进行增加或删除(包括单线程和多线程),保证数据一致性
但事实真的这么简单?看个小demo
运行可以发现,移除 “hello” 或 “java” 都会引发 ConcurrentModificationException
异常,但是移除"world"却不会,事实就是这样。
点开引发异常的 iterator.next() 方法源码可以看到,异常是因为
modCount和expectedModCount的值不同,我们知道在add或者remove修改集合时,属于集合属性的modCount会自增1,而expectedModCount属于内部Itr类,初始化值为modCount后不再改变,所以才导致二者不相同而抛出异常。
但是,删除world会导致size减小1,使得我们的for循环中 iterator.hasNext();
条件不成立,所以不会执行循环体,也就不会在next方法中抛出异常了。
注意这里的cursor是指向下一个元素的index,当迭代到world时,cursor的值是2,而因为我们删除了一个值导致size从3变成2,于是cursor != size
返回 false, for循环的条件不满足了。
最终我们得出结论:移除集合的倒数第二个元素不会引发 ConcurrentModificationException
异常。
但是这个结论没有什么用处,为什么呢,因为虽然没有异常了,但是迭代的结果却是错误的,可以自行输出查看