程序员社区

(Java集合面试题)fail-fast与fail-safe有什么区别?

Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响。java.util包下面的所有的集合类都是快速失败的,而java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。

快速失败

在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。

public class Test {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
            list.add(3);
            System.out.println(list.size());
        }

    }
}

运行结果:

 1
 Exception in thread "main" java.util.ConcurrentModificationException
 3
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    at java.util.ArrayList$Itr.next(ArrayList.java:859)
    at Test.main(Test.java:12)

安全失败

采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

public class Test {

    public static void main(String[] args) {
        List<Integer> list = new CopyOnWriteArrayList<>();
        list.add(1);
        list.add(2);

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
            list.add(3);
            System.out.println("list size:"+list.size());
        }

    }
}

运行结果:

1
list size:3
2
list size:4

其实,在java.util.concurrent 并发包的集合,如 ConcurrentHashMap, CopyOnWriteArrayList等,默认为都是安全失败的。

Java面试题

赞(0) 打赏
未经允许不得转载:IDEA激活码 » (Java集合面试题)fail-fast与fail-safe有什么区别?

一个分享Java & Python知识的社区