Monday 23 May 2016

Concurrentmodification Exception Explained.


In this post we will try to understand why concurrentmodification exception is thrown.

Yes concurrent modification exception is thrown when the structure of a collection is changed within its iterator without using iterator's remove method "But there is a catch, This blogs explains the same"

Now a code sample from the Iterator returned by ArrayList:
    public boolean hasNext() {
        return cursor != size;
    }

    public E next() {
        checkForComodification();
        <stuff>
        return <things>;
    }

    <more methods>

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
Now from this we can figure out that ConcurrentModificationException is thrown in the next() method not hasnext() method.

Take for example(removing element):

public static void main(String[] args) {

List<String> strList = new ArrayList<String>();
strList.add("Sandeep");
strList.add("Raju");

Iterator<String> listItr = strList.iterator();
int i=0;
while(listItr.hasNext()){
System.out.println(i++);
String str = listItr.next();
System.out.println(" String "+ str);
strList.remove(str);
}

}
Now as per above code "The structure of arraylist is getting changed inside the iterator " So it should throw ConcurrentModificationException but it will not. The output will be

Output:

Loop count 0
Name Sandeep

Explanation :

When the program starts it inserts 2 elements into the list. In the while loop of the iterator we print the the loop count, then we print the string value, and the loop removes the same string value. Now since the value has been removed from the list, When the control goes for the second round, the hasnext() will give you false and the control will not go inside the loop anymore. So no ConcurrentModificationException will be thrown as we didn't even reached the next method.


Now in the same case consider the following example (adding element)

public static void main(String[] args) {

List<String> strList = new ArrayList<String>();
strList.add("Sandeep");
strList.add("Raju");

Iterator<String> listItr = strList.iterator();
int i=0;
while(listItr.hasNext()){
System.out.println(i++);
String str = listItr.next();
System.out.println(" String "+ str);
strList.add(str);
}

}

Output:

Loop count 0
Name Sandeep
Loop count 1
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 com.sandeep.java7.ConcModificationException.main(ConcModificationException.java:20)



Explanation :

When the program starts it inserts 2 elements into the list. In the while loop of the iterator we print the the loop count, then we print the string value, and the loop adds the same string value again. Now a new element has been added into the list, When the control goes for the second round, the hasnext() will give you true because we still have elements to be traversed  and the control will  go inside the loop. Now when the control reaches the next() method it comes to know that the structure of the collection has been modified hence it will trow the ConcurrentModificationException.





No comments:

Post a Comment