java.util包下面的所有集合类都是快速失败的,而Java.util.concurent包下面的集合类都是安全失败。 快速失败 迭代器会抛出ConcurentModificationException异常,而安全失败的迭代器永远 不会抛出这样的异常
为什么在使用迭代器遍历集合时,修改集合会抛出异常? 原因是:迭代器在遍历集合时会直接访问集合中的内容,并且在遍历的过程中使用一个modCount的变量,集合在遍历期间如果发生了变化,就会改变modCount的值。 每当迭代器使用 hashNext()/next() 遍历下一个元素之前都会检测 modCount 变量是否为 expectedModCount 值,是的话就返回遍历;否则抛出异常,终止遍历。
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有的集合内容在拷贝的集合上进行遍历。 由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,故不会抛 ConcurrentModificationException 异常
public class FailSafeDemo { public static void main(String[] args) { ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); concurrentHashMap.put("111", 1); concurrentHashMap.put("222", 2); concurrentHashMap.put("3333", 3); Set set = concurrentHashMap.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); concurrentHashMap.put("下次循环正常执行", 4); } System.out.println("程序结束"); } } 111=1 222=2 3333=3 程序结束 Process finished with exit code 0最后说明一下,快速失败和安全失败是对迭代器而言的。并发环境下建议使用 java.util.concurrent 包下的容器类,除非没有修改操作。