In this post, we will see Fail fast and fail safe example in java.
Fail fast Iterator- When we try to modify the internal structure of collection while iterating, it throws ConcurrentModificationException, is fail fast iterator.
Example 1 – Fail Fast example in case of ArrayList
package failfastandfailsafe; import java.util.*; public class Example { public static void main(String[] args) { List<String> listObject = new ArrayList<>(); listObject.add("ram"); listObject.add("mohan"); listObject.add("shyam"); listObject.add("mohan"); listObject.add("ram"); Iterator it = listObject.iterator(); while (it.hasNext()) { listObject.add("raju"); System.out.println(it.next()); } } }
Output is –
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at failfastandfailsafe.Example.main(Example.java:21)
Before moving further we will see why we get this exception
If you notice the exception stack problem started from next() method. Inside next() method there is another method checkForComodification() where it has been thrown ConcurrentModificationException on basis of some condition. Let’s see what’s going on inside next() and checkForComodification() method.
next() method –
public E next() { checkForComodification(); int i = cursor; // some more code return (E) elementData[lastRet = i]; }
checkForComodification() –
void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
Inside checkForComodification() method there is a condition if modcount is not equal to expectedModCount throw ConcurrentModificationException(extending RuntimException). In our case when we do listObject.add(“raju”) inside while loop the value of modCount become 6 but value of expectedCount is still 5. That’s why we get ConcurrentModificationException. Ok! So it seems we have problem in next() method. That is correct. What will hapeen if we don’t use next() method for printing the elements. We can use enhanced for loop.
import java.util.*; public class Example { public static void main(String[] args) { List<String> listObject = new ArrayList<>(); listObject.add("ram"); listObject.add("mohan"); listObject.add("shyam"); listObject.add("mohan"); listObject.add("ram"); for (String s : listObject ){ listObject.add("raju"); System.out.println(s); } } }
Output is –
ram
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 Example.main(Example.java:13)
Still we are getting ConcurrentModificationException. Why? We are not iterating using Iterator. Even we use enhanced for loop, internally next() method is getting called.
Example 2 – Fail Fast example in case of HashsMap
package failfastandfailsafe; import java.util.*; public class Example { public static void main(String[] args) { Map<Integer, String> hashmapObject = new HashMap<>(); hashmapObject.put(2, "ram"); hashmapObject.put(3, "mohan"); hashmapObject.put(4, "Bangalore"); hashmapObject.put(5, "Rakesh"); // we will iterate using Iterator Iterator<Map.Entry<Integer, String>> iterator = hashmapObject .entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Integer, String> entry = iterator.next(); hashmapObject.put(6, "Rakesh"); System.out.println("Key is = " + entry.getKey() + ", Value is = " + entry.getValue()); } } }
Output is –
Key is = 2, Value is = ram
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$EntryIterator.next(Unknown Source)
at java.util.HashMap$EntryIterator.next(Unknown Source)
at failfastandfailsafe.Example.main(Example.java:21)
If we look into exception stack, in HashMap we have an inner class HashIterator which contains nextNode() method. Inside this method, similar logic has been defined.
final Node<K,V> nextNode() { Node<K,V>[] t; Node<K,V> e = next; if (modCount != expectedModCount) throw new ConcurrentModificationException(); //more code }
Example 3 – Using Iterator remove() method
package failfastandfailsafe; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; public class Example { public static void main(String[] args) { List<String> listObject = new ArrayList<>(); listObject.add("ram"); listObject.add("mohan"); listObject.add("shyam"); listObject.add("mohan"); listObject.add("ram"); Iterator it = listObject.iterator(); while (it.hasNext()) { System.out.println(it.next()); it.remove(); } System.out.println("After it.remove() size of list is "+listObject.size()); } }
Output is –
ram
mohan
shyam
mohan
ram
After it.remove() size of list is 0
[stextbox id=’info’]We are not getting any exception when we use Iterator’s remove() method. Also our list is getting modified i.e size is zero.[/stextbox]
Fail safe Iterator – In JDK1.5 some new classes(CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap etc) which doesn’t throw ConcurrentModificationException even we modify the structure of List, Set or Map while iterating. These classes work on clone or copy of collections Object.
Example –
package failfastandfailsafe; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; public class Example { public static void main(String[] args) { List<String> listObject = new CopyOnWriteArrayList<>(); listObject.add("ram"); listObject.add("mohan"); listObject.add("shyam"); listObject.add("mohan"); listObject.add("ram"); Iterator it = listObject.iterator(); while (it.hasNext()) { listObject.add("raju"); System.out.println(it.next()); } System.out.println("ConcurrentHashMap example ---------"); Map<Integer, String> hashmapObject = new ConcurrentHashMap<>(); hashmapObject.put(2, "ram"); hashmapObject.put(3, "mohan"); hashmapObject.put(4, "Bangalore"); hashmapObject.put(5, "Rakesh"); // we will iterate using Iterator Iterator<Map.Entry<Integer, String>> iterator = hashmapObject .entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Integer, String> entry = iterator.next(); hashmapObject.put(7, "rohan"); System.out.println("Key is = " + entry.getKey() + ", Value is = " + entry.getValue()); } } }
Output is –
ram
mohan
shyam
mohan
ram
ConcurrentHashMap example ———
Key is = 2, Value is = ram
Key is = 3, Value is = mohan
Key is = 4, Value is = Bangalore
Key is = 5, Value is = Rakesh
Key is = 7, Value is = rohan
Let’s see the difference fail fast and fail safe iterator –
Sr No. | Fail Fast | Fail Safe |
---|---|---|
1. | Fail fast works on collections object. | Fail safe work on clone or copy of collection object. |
2. | It throws ConcurrentModificationException when we add some element during iteration. | It does't throw any exception. |
3. | It needs less memory. | It needs extra memory. |
ArraList,HashSet, HashMap etc classes used. | CopyOnWriteArrayList,ConcurrentHashMap classed used. |
That’s all about Fail fast and fail safe example in java. You may like –
- How HashMap works internally in Java.
- How to make List, Set and Map Read Only in Java.
- How to avoid duplicate elements in ArrayList.