ConcurrentModificationException
is thrown if the collection is changed while a thread is traversing over it using iterator. ConcurrentModificationException
can occur both in single threaded as well as multi-threaded programs. For example, following program will throw ConcurrentModificationException
because we are trying to remove element from the list while iterating:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ConcurrentModificationExceptionExample { public static void main(String args[]) { List<String> list = new ArrayList<String>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); Iterator<String> it = list.iterator(); while (it.hasNext()) { String element = it.next(); System.out.println("List Value:" + element); if ("three".equals(element)) list.remove(element); } } }
Output
List Value:one
List Value:two
List Value:three
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at ConcurrentModificationExceptionExample.main(ConcurrentModificationExceptionExample.java:18)
To avoid ConcurrentModificationException
- Convert the list in to an array and then iterate array. This approach is not good in case of large size list.
- Use
CopyOnWriteArrayList
andConcurrentHashMap
if you are using JDK1.5 or higher. - Use
synchronized
block while iterating over list. This approach is not recommended due to performance issues. - Use
remove()
function of iterator to remove element from the collection. But is the case you can remove the current element but not any other element.
Following example shows ConcurrentModificationException
will not be thrown when CopyOnWriteArrayList
is used.
import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class CopyOnWriteArrayListExample { public static void main(String[] args) { List<String> list = new CopyOnWriteArrayList<String>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); Iterator<String> it = list.iterator(); while (it.hasNext()) { String element = it.next(); System.out.println("List Value:" + element); if ("three".equals(element)) list.remove(element); } } }
Output
List Value:one
List Value:two
List Value:three
List Value:four
List Value:five
Following example will demonstrate that ConcurrentModificationException
is not thrown when we use remove() function of iterator.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorRemoveExample { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); Iterator<String> itr = list.iterator(); while (itr.hasNext()) { String element = itr.next(); System.out.println("List Value:" + element); if ("three".equals(element)) itr.remove(); } System.out.println("final list: " + list); } }
Output
List Value:one
List Value:two
List Value:three
List Value:four
List Value:five
final list: [one, two, four, five]