ConcurrentModificationException, Fail-fast and Fail-safe in detail in java


In this Collection framework tutorial we will learn what is fail-fast, fail-safe and java.util.ConcurrentModificationException in java.



Contents of page :
  • What is fail-fast, fail-safe and ConcurrentModificationException in java?
  • SECTION 1 (FAIL-FAST):
    • Iterator returned by ArrayList are fail-fast, means any structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java.
    • Program to show structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java.
      • During execution of program ArrayList and Iterator returned by ArrayList maintains following variables >
      • What is modCount? What is structural modifications in java?
      • Which method cause structural modifications in java?
      • Which method does not cause structural modifications in java?
      • How to use iterator.remove() in java?
      • Below i have attached screenshot to show you variables maintained during runtime.
  • SECTION 2 (FAIL-SAFE) :
    • Iterator returned by CopyOnWriteArrayList are fail-safe, means any structural modification made to CopyOnWriteArrayList during iteration won’t throw any Exception in java.
    • Program to show structural modification made to CopyOnWriteArrayList during iteration  won’t throw any Exception in java.
      • During execution of program CopyOnWriteArrayList and Iterator returned by CopyOnWriteArrayList maintains following variables >
      • So why program did not throw ConcurrentModificationException in java?
      • Below i have attached screenshot to show you variables maintained during runtime in java.

  • Some important classes whose returned iterator is fail-fast, means any structural modification made to these classes during iteration will throw ConcurrentModificationException >

  • Some important classes whose returned iterator is fail-safe, means any structural modification made to these classes during iteration won’t throw any Exception in java >

  • SUMMARY of fail-fast, fail-safe and java.util.ConcurrentModificationException in java >
    • What’s the main difference variables maintained when iteration is done on ArrayList and CopyOnWriteArrayList in java?


What is fail-fast, fail-safe and ConcurrentModificationException in java?

Iterator returned by few Collection framework Classes are fail-fast, means any structural modification made to these classes during iteration will throw ConcurrentModificationException in java.

Iterator returned by few Collection framework Classes are fail-safe, means any structural modification made to these classes during iteration won’t throw any Exception in java.


SECTION 1 (FAIL-FAST) :
Iterator returned by ArrayList are fail-fast, means any structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java.

Example/Program to show structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ConcurrentModificationArrayListExample {
   public static void main(String[] args) {
      List<String> list = new ArrayList<String>();
      list.add("a");
       list.add("b");
       list.add("c");
      
       Iterator<String> iterator = list.iterator();
      
       while(iterator.hasNext()){
       
        String str = iterator.next();
        System.out.print(str+" ");
       
        if(str.equals("b"))
         list.add("b2");   //will throw ConcurrentModificationException
       
       }
      
       System.out.println("\nAfter iteration list is : "+list);
      
   }
}
/*OUTPUT
a b Exception in thread "main" java.util.ConcurrentModificationException
   at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
   at java.util.ArrayList$Itr.next(Unknown Source)
   at com.javaMadeSoEasy.ConcurrentModificationArrayListExample.main(ConcurrentModificationArrayListExample.java:20)
*/

Let’s discuss above program in detail
During execution of program ArrayList and Iterator returned by ArrayList maintains following variables >
Variables maintained by ArrayList -
         > modCount =3  
         > size =3
Variables maintained by Iterator returned by ArrayList -
          >expectedModCount =3
>Initially, cursor=0   > index of next element to return
means it is pointing to 1st element in list, i.e. on 0th index [increments every time when iterator.next() is called]
>Initially, lastRet= -1 > index of last element returned; -1 if no such
[increments every time when iterator.next() is called]

Every time iterator.next() is called it internally calls checkForComodification() to checks for any modification made to list.
        final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
       }

if modCount is not equal to expectedModCount ConcurrentModificationException is thrown.


What is modCount? What is structural modifications in java?
The number of times this list has been structurally modified. Any changes to size of list are called structural modifications in java.

Which method cause structural modifications in java?
add() and remove() method changes size of list. Hence, cause structural modifications.
Every time any of these methods is called modCount is incremented by 1.

Additionally, you may also be interested in knowing what will happen if add() and remove() methods are called subsequently in java?
Subsequent calls made to add() and remove() methods won’t avoid ConcurrentModificationException. Because in this case modCount will be incremented twice by 1.

Which method does not cause structural modifications in java?
set() method does not changes size of list. Hence, does not cause any structural modifications.
Every time set() is called modCount remains unchanged.

How to use iterator.remove() in java?
We can remove elements from ArrayList using iterator’s remove method.
Every time iterator.remove() is called modCount remains unchanged.
But, if iterator.remove() is called before calling iterator.next() than IllegalStateException is thrown.

Below i have attached screenshot to show you variables maintained during runtime.
Note: Program was executed in debug mode. And screenshot was taken when we entered first time in while loop. Hence value of cursor is 0 and lastRet’s is -1.



SECTION 2 (FAIL-SAFE) :
Iterator returned by CopyOnWriteArrayList are fail-safe, means any structural modification made to CopyOnWriteArrayList during iteration won’t throw any Exception in java.


Example/ Program to show structural modification made to CopyOnWriteArrayList during iteration  won’t throw any Exception in java.
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentModificationCopyOnWriteArrayListExample {
   public static void main(String[] args) {
      List<String> list = new CopyOnWriteArrayList<String>();
      list.add("a");
       list.add("b");
       list.add("c");
      
       Iterator<String> iterator = list.iterator();
      
       while(iterator.hasNext()){
 
        String str = iterator.next();
        System.out.print(str+" ");
       
        if(str.equals("b"))
         list.add("b2");   //No ConcurrentModificationException
       
       }
      
       System.out.println("\nAfter iteration list is : "+list);
      
   }
}
/*OUTPUT
a b c
After iteration list is : [a, b, c, b2]
*/

Let’s discuss above program in detail
During execution of program CopyOnWriteArrayList and Iterator returned by CopyOnWriteArrayList maintains following variables >
Variables maintained by CopyOnWriteArrayList -
         > lock > because CopyOnWriteArrayList  is thread safe.
Variables maintained by Iterator returned by CopyOnWriteArrayList -
          >snapshot, it is copy of CopyOnWriteArrayList (not the original CopyOnWriteArrayList)
>Initially, cursor=0   > index of next element to return
means it is pointing to 1st element in list, i.e. on 0th index [increments every time when iterator.next() is called]
It’s important to know that cursor is maintained on snapshot, rather than on list as in case of ArrayList (When iterating on ArrayList, cursor is maintained on ArrayList, because no snapshot kind of variable exists there).

So why program did not throw ConcurrentModificationException?
Because when list.iterator() is called, a variable called snapshot is created which is copy of list (not the original list). Hence, iteration does not care about structural modifications made to list.

Below i have attached screenshot to show you variables maintained during runtime.
Note: Program was executed in debug mode. And screenshot was taken when we entered first time in while loop. Hence value of cursor is 0.



Some important classes whose returned iterator is fail-fast, means any structural modification made to these classes during iteration will throw ConcurrentModificationException in java >

The iterators returned by the iterator() method of the collections returned by all three Map's “collection view methods" are fail-fast >
map.keySet().iterator(), map.values().iterator(), map.entrySet().iterator()


Some important classes whose returned iterator is fail-safe, means any structural modification made to these classes during iteration won’t throw any Exception in java >

The iterators returned by the iterator() method of the collections returned by all three Map's “collection view methods" are fail-safe >
map.keySet().iterator(), map.values().iterator(), map.entrySet().iterator()




SUMMARY of fail-fast, fail-safe and java.util.ConcurrentModificationException in java >
What’s the main difference variables maintained when iteration is done on ArrayList and CopyOnWriteArrayList in java?
Iterator returned by ArrayList maintains variables called modCount (The number of times this list has been structurally modified. Any changes to size of list are called structural modifications).
So, any structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java

Iterator returned by CopyOnWriteArrayList maintains variables called snapshot ( it is copy of array (not the original array)
So, any structural modification made to CopyOnWriteArrayList during iteration won’t throw any Exception.


So in this Collection framework tutorial we learned what is fail-fast, fail-safe and java.util.ConcurrentModificationException in java.


Having any doubt? or you you liked the tutorial! Please comment in below section.
Please express your love by liking JavaMadeSoEasy.com (JMSE) on facebook, following on google+ or Twitter.



RELATED LINKS>

Basic Collection - All properties in tabular form >

Collection - List, Set and Map all properties in tabular form



Collection hierarchy >

List hierarchy in java - Detailed - ArrayList, LinkedList, vector, CopyOnWriteArrayList classes


Set hierarchy in java - Detailed - HashSet, CopyOnWriteArraySet, LinkedHashSet, TreeSet, ConcurrentSkipListSet, EnumSet classes


Map hierarchy in java - Detailed - HashMap, Hashtable, ConcurrentHashMap, LinkedHashMap, TreeMap, ConcurrentSkipListMap, IdentityHashMap, WeakHashMap, EnumMap classes


Must read for you :

No comments:

Post a Comment