Fail Fast与Fail Safe的区别

来源:互联网 发布:淘宝网韩版卫衣 编辑:程序博客网 时间:2024/04/30 14:41

Fail Fast

Fail Fast Iterator在遍历集合时,若该集合发生了结构性的改变,则将抛出 ConcurrentModification 异常。例如:

        Map<String, String> premiumPhone = new HashMap<String, String>();        premiumPhone.put("Apple", "iPhone");        premiumPhone.put("HTC", "HTC one");        premiumPhone.put("Samsung", "S5");        Iterator<String> iterator = premiumPhone.keySet().iterator();        while (iterator.hasNext()) {            System.out.println(premiumPhone.get(iterator.next()));            premiumPhone.put("Sony", "Xperia Z");        }

如果将while循环内的语句

premiumPhone.put("Sony", "Xperia Z");

改成如下,则不会抛出ConcurrentModification 异常。因为只修改了值,没有改变集合的结构

premiumPhone.put("HTC", "Xperia Z");

Fail Fast检测集合结构改变的原理,Iterator直接访问集合的数据结构,它保留一个标志”mods”,在Iterator每次调用hasNext()或者是next()方法时,首先检测”mods”状态,如果结构已经改变,则抛出异常。

Fail Safe

Fail Safe Iterator的实现原理是,先将原集合拷贝一份,在拷贝上开展遍历,因此不会引起ConcurrentModification 异常。因此,Fail Safe Iterator存在两个缺陷:
1. 引入了额外的空间开销
2. 遍历时读取的数据,并不能保证是最新的

一个Fail Safe Iterator的例子如下:

        ConcurrentHashMap<String, String> premiumPhone = new ConcurrentHashMap<String, String>();        premiumPhone.put("Apple", "iPhone");        premiumPhone.put("HTC", "HTC one");        premiumPhone.put("Samsung", "S5");        Iterator<String> iterator = premiumPhone.keySet().iterator();        while (iterator.hasNext()) {            System.out.println(premiumPhone.get(iterator.next()));            premiumPhone.put("Sony", "Xperia Z");        }
0 0