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");
}