Sunday, May 29, 2016

Fail Fast And Fail Safe Iterator In Java

In this post we will be discussing about fail-fast and fail-safe iterators present in java.


Sections in this post: 
  1. Concurrent Modification
  2. Fail Fast Iterator
  3. How Fail Fast Iterator works
  4. Fail Safe Iterator
  5. Examples
  6. Difference between fail fast and fail safe iterator

What is Concurrent Modification?

When one or more threads are iterating over a collection and in between, one of the thread changes the structure of the collection (either adding the element to the collection or by deleting the element from the collection or by updating the value at particular position in the collection) is known as Concurrent Modification.

Fail fast Iterator

While iterating through the collection, Fail fast iterators instantly throws Concurrent Modification Exception if there is structural modification  of the collection. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.


How  Fail  Fast Iterator  come to know that the internal structure is modified ?

Fail Fast Iterators read underlying collection object data directly. The internal data should not be modified while iterating through the collection. To ensure this it maintains an internal  flag "modCount". Iterator checks the "modCount" flag whenever it gets the next value (using hasNext() method and next() method). Value of mods flag changes whenever there is an structural modification. Thus indicating iterator to throw "ConcurrentModificationException".


Fail safe Iterator


Fail Safe Iterator makes a copy of the underlying collection object and iterates over the copied collection object. Any structural modification done to the iterator affects the copied data structure so, original data structure remains  structurally unchanged. Hence, no ConcurrentModificationException is thrown by the fail safe iterator.


Two  issues associated with Fail Safe Iterator are :

  1. Overhead of maintaining the copied data structure i.e memory. 
  2. Fail safe iterator does not guarantee that the data being read is the latest data from the underlying original collection object.

Lets see a fail fast iterator example:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class FailFastExample
{
    public static void main(String[] args)
    {
        Map<string,String> premiumPhone =  
                       new HashMap<string,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");
        
        Iterator iterator = premiumPhone.keySet()
                                         .iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(premiumPhone.get(
                                    iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
    }
}
Output:                                                  
                    ================================================================

      iPhone 

      Exception in thread "main" java.util.ConcurrentModificationException

      at java.util.HashMap$HashIterator.nextEntry(Unknown Source)

      at java.util.HashMap$KeyIterator.next(Unknown Source)

      at FailFastExample.main(FailFastExample.java:20)

We can see that as soon as we try to  put a new entry ("Sony", "Xperia Z"), fail-fast iterator immediately throws ConcurrentModificationException.

lest's see Fail Safe Iterator Example now :

import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;

public class FailSafeExample
{
    public static void main(String[] args)
    {
        Map<string,String> premiumPhone = 
                     new ConcurrentHashMap<string,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");
        
        Iterator iterator = premiumPhone.keySet()
                                          .iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(premiumPhone
                               .get(iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
    }
}

Output:
=============================================
S5

HTC one

iPhone

Below table summarizes major differences between fail-fast and fail-safe iterator.

Fail Fast Iterator Fail Safe Iterator
Throw ConcurrentModification Exception Yes No
Clone object No Yes
Memory Overhead No Yes
Examples HashMap,Vector,ArrayList,HashSet CopyOnWriteArrayList, ConcurrentHashMap