Fail Fast and Fail Safe Iterators in Java
https://www.geeksforgeeks.org/fail-fast-fail-safe-iterators-java/
Fail Fast and Fail Safe Iterators in Java
In this article, I am going to explain how those collections behave which doesn’t iterate as fail-fast. First of all, there is no term as fail-safe given in many places as Java SE specifications does not use this term. I am using fail safe to segregate between Fail fast and Non fail-fast iterators.
Concurrent Modification: Concurrent Modification in programming means to modify an object concurrently when another task is already running over it. For example, in Java to modify a collection when another thread is iterating over it. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw ConcurrentModificationException if this behavior is detected.
Fail Fast And Fail Safe Iterators in Java
Iterators in java are used to iterate over the Collection objects.Fail-Fast iterators immediately throw ConcurrentModificationException if there is structural modification of the collection. Structural modification means adding, removing or updating any element from collection while a thread is iterating over that collection. Iterator on ArrayList, HashMap classes are some examples of fail-fast Iterator.
Fail-Safe iterators don’t throw any exceptions if a collection is structurally modified while iterating over it. This is because, they operate on the clone of the collection, not on the original collection and that’s why they are called fail-safe iterators. Iterator on CopyOnWriteArrayList, ConcurrentHashMap classes are examples of fail-safe Iterator.
How Fail Fast Iterator works ?
To know whether the collection is structurally modified or not, fail-fast iterators use an internal flag called modCount which is updated each time a collection is modified.Fail-fast iterators checks the modCountflag whenever it gets the next value (i.e. using next() method), and if it finds that the modCount has been modified after this iterator has been created, it throws ConcurrentModificationException.
// Java code to illustrate// Fail Fast Iterator in Javaimport java.util.HashMap;import java.util.Iterator;import java.util.Map;public class FailFastExample { public static void main(String[] args) { Map<String, String> cityCode = new HashMap<String, String>(); cityCode.put("Delhi", "India"); cityCode.put("Moscow", "Russia"); cityCode.put("New York", "USA"); Iterator iterator = cityCode.keySet().iterator(); while (iterator.hasNext()) { System.out.println(cityCode.get(iterator.next())); // adding an element to Map // exception will be thrown on next call // of next() method. cityCode.put("Istanbul", "Turkey"); } }} |
Run on IDE
Output :
India
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$KeyIterator.next(HashMap.java:1466)
at FailFastExample.main(FailFastExample.java:18)
Important points of fail-fast iterators :
- These iterators throw ConcurrentModificationException if a collection is modified while iterating over it.
- They use original collection to traverse over the elements of the collection.
- These iterators don’t require extra memory.
- Ex : Iterators returned by ArrayList, Vector, HashMap.
Note 1(from java-docs): The fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
Note 2 : If you remove an element via Iterator remove() method, exception will not be thrown. However, in case of removing via a particular collection remove() method, ConcurrentModificationException will be thrown. Below code snippet will demonstrate this:
// Java code to demonstrate remove// case in Fail-fast iteratorsimport java.util.ArrayList;import java.util.Iterator;public class FailFastExample { public static void main(String[] args) { ArrayList<Integer> al = new ArrayList<>(); al.add(1); al.add(2); al.add(3); al.add(4); al.add(5); Iterator<Integer> itr = al.iterator(); while (itr.hasNext()) { if (itr.next() == 2) { // will not throw Exception itr.remove(); } } System.out.println(al); itr = al.iterator(); while (itr.hasNext()) { if (itr.next() == 3) { // will throw Exception on // next call of next() method al.remove(3); } } }} |
Run on IDE
Output :
[1, 3, 4, 5]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at FailFastExample.main(FailFastExample.java:28)
Fail Safe Iterator
First of all, there is no term as fail-safe given in many places as Java SE specifications does not use this term. I am using this term to demonstrate the difference between Fail Fast and Non-Fail Fast Iterator. These iterators make a copy of the internal collection (object array) and iterates over the copied collection. Any structural modification done to the iterator affects the copied collection, not original collection. So, original collection remains structurally unchanged.
- Fail-safe iterators allow modifications of a collection while iterating over it.
- These iterators don’t throw any Exception if a collection is modified while iterating over it.
- They use copy of original collection to traverse over the elements of the collection.
- These iterators require extra memory for cloning of collection. Ex : ConcurrentHashMap, CopyOnWriteArrayList
Example of Fail Safe Iterator in Java:
// Java code to illustrate// Fail Safe Iterator in Javaimport java.util.concurrent.CopyOnWriteArrayList;import java.util.Iterator;class FailSafe { public static void main(String args[]) { CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<Integer>(new Integer[] { 1, 3, 5, 8 }); Iterator itr = list.iterator(); while (itr.hasNext()) { Integer no = (Integer)itr.next(); System.out.println(no); if (no == 8) // This will not print, // hence it has created separate copy list.add(14); } }} |
Run on IDE
Output:
1
3
5
8
Also, those collections which don’t use fail-fast concept may not necessarily create clone/snapshot of it in memory to avoid ConcurrentModificationException. For example, in case of ConcurrentHashMap, it does not operate on a separate copy although it is not fail-fast. Instead, it has semantics that is described by the official specification as weakly consistent(memory consistency properties in Java). Below code snippet will demonstrate this:
Example of Fail-Safe Iterator which does not create separate copy
// Java program to illustrate// Fail-Safe Iterator which// does not create separate copyimport java.util.concurrent.ConcurrentHashMap;import java.util.Iterator;public class FailSafeItr { public static void main(String[] args) { // Creating a ConcurrentHashMap ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>(); map.put("ONE", 1); map.put("TWO", 2); map.put("THREE", 3); map.put("FOUR", 4); // Getting an Iterator from map Iterator it = map.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); System.out.println(key + " : " + map.get(key)); // This will reflect in iterator. // Hence, it has not created separate copy map.put("SEVEN", 7); } }} |
Run on IDE
Output
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7
Note(from java-docs) : The iterators returned by ConcurrentHashMap is weakly consistent. This means that this iterator can tolerate concurrent modification, traverses elements as they existed when iterator was constructed and may (but not guaranteed to) reflect modifications to the collection after the construction of the iterator.
Difference between Fail Fast Iterator and Fail Safe Iterator
The major difference is fail-safe iterator doesn’t throw any Exception, contrary to fail-fast Iterator.This is because they work on a clone of Collection instead of the original collection and that’s why they are called as the fail-safe iterator.
Fail Fast and Fail Safe Iterators in Java的更多相关文章
- fail fast和fail safe策略
优先考虑出现异常的场景,当程序出现异常的时候,直接抛出异常,随后程序终止 import java.util.ArrayList; import java.util.Collections; impor ...
- 快速失败(fail—fast)和 安全失败(fail—safe)
快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...
- 【问题】Could not locate PropertySource and the fail fast property is set, failing
这是我遇到的问题 Could not locate PropertySource and the fail fast property is set, failing springcloud的其他服务 ...
- Java集合框架中的快速失败(fail—fast)机制
fail-fast机制,即快速失败机制,是java集合框架中的一种错误检测机制.多线程下用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除),则会抛出Concurre ...
- java中fail-fast 和 fail-safe的区别
java中fail-fast 和 fail-safe的区别 原文地址:http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fa ...
- java fail-fast和fail-safe
快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(如增加.删除等),则会抛出Concurrent Modification Exception. ...
- 面试题思考:java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
- java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
- Java中的fail-fast和 fail-safe 的区别
在我们详细讨论这两种机制的区别之前,首先得先了解并发修改. 1.什么是同步修改? 当一个或多个线程正在遍历一个集合Collection,此时另一个线程修改了这个集合的内容(添加,删除或者修改).这就是 ...
随机推荐
- 在EntityFramework6中管理DbContext的正确方式——4DbContextScope:一个简单的,正确的并且灵活的管理DbContext实例的方式(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
- 制作MACOSX10.10.3/10.9安装启动盘U盘的教程
下载MACOSX 10.10.3/10.9镜像文件,下载地址http://www.chinamac.com/download/mac14032.html1.准备好你需要的大于等于6G以上的U盘或者移动 ...
- 【spring boot】【log4jdbc】使用log4jdbc打印mybatis的sql和Jpa的sql语句运行情况
在spring boot 中使用mybatis 想看到sql语句的运行情况. 虽然按照 之前说的配置了 logging.level.你的mapper包位置 = debug 但是依旧没有起作用. 所以采 ...
- IOS学习之基于IOS7的tab bar
转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/28129473 作者:小马 什么是tabbar? 先几张图: 上图中蓝色框 ...
- 利用UIWebView获取userAgent需要注意的地方
网络通信有时候需要传递参数userAgent,iOS中获取userAgent很简单. UIWebView* webView = [[UIWebView alloc] initWithFrame:CGR ...
- 附4 springboot源码解析-run()
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); / ...
- 你可能不知道的5 个强大的HTML5 API 函数
HTML5提供了一些非常强大的JavaScript和HTML API,来帮助开发者构建精彩的桌面和移动应用程序.本文将介绍5个新型的API,希望对你的开发工作有所帮助. 1. 全屏API(Fulls ...
- 【用jQuery来判断浏览器的类型】及【javascript获取用户ip地址】
用jQuery来判断浏览器的类型,主要是使用$.browser这个工具类,使用方法: $.browser.['浏览器关键字'] //谷歌浏览器.360浏览器等其他一些浏览器,没有专门的判断 funct ...
- C#版查杀本地/远程进程工具
xkill [原创] Author: R&S E-mail: yrwithsh@vip.sina.com HomePage: fz5fz.yeah.net Date: 10/04/2003 u ...
- IOS调试—断点调试以及动态输出
在开发App的过程中,需要反复的修改和优化我们的代码,特别是当程序出现bug,需要快速的找出错误的原因,进行修改,以保证程序的正确执行. 断点调试,是最常用最简单的一种调试方式,可以一步步跟踪程序执行 ...