Thursday, June 19, 2014

Fail-Fast And Fail-Safe Iterators/ConcurrentModificationException

Fail-Fast And Fail-Safe Iterators/ConcurrentModificationException
Quite few times, while iterating over a List or collection and trying to perform some operations, we get ConcurrentModificationException. The idea behind getting to know the true reason for this is to know the type of iterator or to be precise, the type of collection that we are iterating on.
There are 2 types of Iterators:
1. Fail-Fast
2. Fail-Safe

The Fail-Fast iterators are ones which fails (And throws ConcurrentModificationException) when the collection's structure (i.e its size) changes upon iteration i.e whenever we add or remove an item from a collection or whenever a different thread adds/removes an item from a collection which is being interating currently, the ConcurrentModificationException is thrown. Collection Classes in java.util uses Fail-Fast iterators
Fail-Safe iterators are designed to overcome this. The classes in the package java.util.concurrent uses Fail-Safe iterators. i.e they do not throw ConcurrentModificationException when the collection structure i.e size changes while it is being in the middle of iteration
Looking at the example below, we see that Iterators on ArrayList from java. util package throws ConcurrentModificationException when during the iteration, we try to add another item to the ArrayList and hence change the structure of the collection. However, CopyOnWriteArrayList class in java.util.concurrent package uses Fail-Safe interators and hence, they do not throw the exception and are thread safe.
package com.sample.collectionsexamples;

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

public class FailFastAndFailSafeIteratorDemo {
 
   public static void main(String[] args) {
     List arrayList = new ArrayList();
     List copyOnWriteArrayList = new CopyOnWriteArrayList<>();
 arrayList.add(10);
 arrayList.add(20);
 arrayList.add(30);
 arrayList.add(40);
  
 copyOnWriteArrayList.add(10);
 copyOnWriteArrayList.add(20);
 copyOnWriteArrayList.add(30);
 copyOnWriteArrayList.add(40);
  
 iterateOperation("CopyOnWriteArrayList",copyOnWriteArrayList);
 iterateOperation("ArrayList", arrayList);
  
 }
 
 static void iterateOperation(String type, List numbers) {
   System.out.println("Iterating and adding item on: "+type);
       Iterator itr = numbers.iterator();
   while(itr.hasNext()) {
  // Add another integer 50 after 40
  // This code to add will fail for ArrayList 
                // throwing ConcurrentModificationException
  // But it works fine for CopyOnWriteArrayList
      if(itr.next() == 40) {
     numbers.add(50);
   }
 }
 System.out.println("Items in the list "+type+" = "+numbers);
} 

}

No comments:

Post a Comment