Saturday, May 2, 2020

Fail-Fast Vs Fail-Safe Iterator In Java

Difference between Fail Fast Iterator and Fail Safe Iterator.

ConcurrentModificationException: The ConcurrentModificationException is a RuntimeException. ConcurrentModificationException has been occurs when a collection object is trying to modify concurrently. While it is not permissible. This exception usually thrown while working with Java Collection classes like list, set map.

Fail Fast Iterator: Fail-Fast iterators throw ConcurrentModificationException if a collection is modified(add or remove elements) while iterating over it.The iterators returned by ArrayList iterator() and listIterator() methods are fail fast:
Example:- 1
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FailFastExampleList {

 public static void main(String[] args) {
  List<String> list = new ArrayList<String>();

  // Add element into list
  list.add("element1");
  list.add("element2");
  list.add("element3");
  list.add("element4");

  // Get an iterator.
  Iterator<String> ite = list.iterator();
  // after create iterator, if we want to remove element from list then it will
  // throw ConcurrentModificationException exception
  // list.remove(0);
  while (ite.hasNext()) {
   System.out.println(ite.next());
   // if we want to add or remove element from list in between while iterating
   // element it will throw ConcurrentModificationException exception
   // list.add("element5");
   list.remove("element2");
  }
 }
}
So it is clear from the above example if we add or remove element from a collection it will throw ConcurrentModificationException.
Output:-
element1
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
 at java.util.ArrayList$Itr.next(Unknown Source)
 at FailFastExampleList.main(FailFastExampleList.java:22)
Example:- 2

import java.util.HashMap;
import java.util.Map;

public class FailFastExampleMap {

 public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<String, Integer>();

  // Insert some sample key-value pairs.
  map.put("Key1", 1);
  map.put("Key2", 2);
  map.put("Key3", 3);

  // if we want to put or remove element from map in between while iterating
  // element it will throw ConcurrentModificationException exception
  for (String key : map.keySet()) {
   if (map.get(key) == 1) {
    //map.remove(key);
    map.put("key4", 4);
   }
  }
 }
}
Output:-
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextNode(Unknown Source)
 at java.util.HashMap$KeyIterator.next(Unknown Source)
 at FailFastExampleMap.main(FailFastExampleMap.java:16)

Points to be noted about fail-fast iterators :
  • These iterators throw ConcurrentModificationException if a collection is modified while iterating over it. 
  • These iterators throw ConcurrentModificationException because they use original collection to traverse the elements of the collection. 
  • In these iterators does not require the extra memory space because they use original collection to traverse the elements of the collection. 

Example : Iterators returned by ArrayList, LinnkedList, HashMap, Vector etc.

 Fail Safe Iterator:- 

  • Fail-safe iterators does not throw the ConcurrentModificationException (don’t throw any Exception) its allow modifications of a collection while iterating over it.
  • Because there copy of original collection is used to traverse over the elements of the collection.
  • These iterators require extra memory space to clone the collection.
Example : Concurrent Collections like ConcurrentHashMap, CopyOnWriteArrayList

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeExampleList {

 public static void main(String[] args) {
  CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
  // Add element into list
  list.add("element1");
  list.add("element2");
  list.add("element3");
  list.add("element4");

  // Get an iterator.
  Iterator<String> ite = list.iterator();
  list.remove(0);
  while (ite.hasNext()) {
   System.out.println(ite.next());
   list.add("element5");
   list.remove("element2");
  }
 }
}
Output:
element1
element2
element3
element4

Note:- If you notice in the above example, there is no impact of add or remove  element CopyOnWriteArrayList list because its use copy of origonal collection. 

No comments:

Post a Comment