What is ConcurrentModificationException , how is it caused and how can it be prevented ? (Part 2- ArrayLists)

In the previous article, we saw with an example of HashMap  how a ConcurrentModificationException is caused. In this article ,we will see how it happens in case of Lists. The basics are the same as in the example of a HashMap.

When the structure of a list is modified by adding or removing an element from the list while an iterator is traversing over it, a ConcurrentModificationException is caused. This is because just like HashMap , an ArrayList also maintains a count of the times the structure of the list is modified (modCount). When an iterator is obtained on that list, it creates its own expectedCount which is set to the modCount value . Any addition or removal from the list will change the modCount.When the iterator compares the modCount with expectedCount whenever iterator's next() method is called , it throws the ConcurrentModification exception if it finds a difference.Such an iterator is said to be fail-fast.

When we use CopyOnWriteArrayList instead of an ArrayList, we don't get this exception. This is because , the iterator of a CopyOnWriteArrayList works on a snapshot of the original list. The iterator may not be able to see the change made to the structure of the original list for this reason.But, it does not fail by throwing the exception and is said to be fail-safe iterator.

Following is an example of ConcurrentModificationException got on using ArrayList:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package in.blogspot.pallavisonal;

import java.util.ArrayList;
import java.util.Iterator;

public class NotSafeArrayList {
 
 private ArrayList<Integer> myList;
 
 public NotSafeArrayList(ArrayList<Integer> myList){
  this.myList=myList;
 }

 public static void main(String[] args) {
  ArrayList<Integer> aList = new ArrayList<>();
  aList.add(1);
  aList.add(2);
  aList.add(3);
  NotSafeArrayList nsAList = new NotSafeArrayList(aList);
  System.out.println(aList);
  Iterator<Integer> iter = nsAList.myList.iterator();
  while(iter.hasNext()){
   if(iter.next() == 2){
    aList.add(4); 
   }
  }
  System.out.println(aList);
 }

}

Output:
[1, 2, 3]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.explore.pallavi.NotSafeArrayList.main(NotSafeArrayList.java:23)

The following example shows how we can prevent the ConcurrentModifcation Exception using CopyOnWriteArrayList which uses fail-safe iterators:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package in.blogspot.pallavisonal;

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

public class SafeArrayList {
    private CopyOnWriteArrayList<Integer> myList;
 
 public SafeArrayList(CopyOnWriteArrayList<Integer> myList){
  this.myList=myList;
 }

 public static void main(String[] args) {
  CopyOnWriteArrayList<Integer> aList = new CopyOnWriteArrayList<>();
  aList.add(1);
  aList.add(2);
  aList.add(3);
  SafeArrayList nsAList = new SafeArrayList(aList);
  System.out.println(aList);
  Iterator<Integer> iter = nsAList.myList.iterator();
  while(iter.hasNext()){
   if(iter.next() == 2){
    aList.add(4); 
   }
  }
  System.out.println(aList);
 }

}

Output:
[1, 2, 3]
[1, 2, 3, 4]

Comments

Popular posts from this blog

Day#3 of Java Programming Practice- Longest word of a Sentence

Book Review: Those Pricey Thakur Girls

Day# 5 of Java Programming Practice- Change the first letter of each word in a sentence to Uppercase.