Why do you get a ConcurrentModificationException when using an iterator?

The reason why you would get a ConcurrentModificationException
The java.util Collection classes are fail-fast, which means that if one thread changes a collection while another
thread is traversing it through with an iterator the iterator.hasNext() or iterator.next() call will throw ConcurrentModificationException . Even the synchronized collection wrapper classes SynchronizedMap and SynchronizedList are only conditionally thread-safe, which means all individual operations are thread-safe but compound operations where flow of control depends on the results of previous operations may be subject to threading issues.

Collection myCollection = new ArrayList(10);

myCollection.add("123");
myCollection.add("456");
myCollection.add("789");

for (Iterator it = myCollection.iterator(); it.hasNext();) {
   String myObject = (String)it.next();
   System.out.println(myObject);
   if (someConditionIsTrue) {
           myCollection.remove(myObject); //can throw ConcurrentModificationException in single as
                                          //well as multi-thread access situations.
}
}

Multi-Threaded Access Siutation

Solution 1

You can convert your list to an array with list.toArray() and iterate on the array. This approach is not
recommended if the list is large.

Solution 2

You can lock the entire list while iterating by wrapping your code within a synchronized block. This approach
adversely affects scalability of your application if it is highly concurrent.

Solution 3

If you are using JDK 1.5 then you can use the ConcurrentHashMap and CopyOnWriteArrayList classes,
which provide much better scalability and the iterator returned by ConcurrentHashMap.iterator() will not throw
ConcurrentModificationException while preserving thread-safety

Single-thread access Situation:

Use:

it.remove(); // removes the current object via the Iterator “it” which has a reference to
// your underlying collection “myCollection”. Also can use solutions 1-3.

Avoid:

myCollection.remove(myObject); // avoid by-passing the Iterator. When it.next() is called, can throw the exception
// ConcurrentModificationException

If you had used any Object to Relational (OR) mapping frameworks like Hibernate, you may have encountered this exception ConcurrentModificationException when you tried to remove an object from a collection such as a java.util Set with the intention of deleting that object from the underlying database. This exception is not caused by Hibernate but rather caused by your java.util.Iterator (i.e. due to your it.next() call). You can use one of the solutions given above.

Published by anthonykuong

Anthony is a versatile Software professional with around 10 years of experience. He is a Full Stack developer experienced with clients in the Financial, Health and Supply Chain industries. He is experienced with MVC frameworks ( Spring Boot) , SPA frameworks ( Angular , VueJS), and also supports automated build deployments and packaging for development, qa, and production servers.. He has delivered rich user experience using Modern web technologies and techniques such are HTML5, CSS3, ECMAScript 6 (ES6)/ ECMAScript 2015, CSS pre-processors (SASS, Less), JavaScript build tools (Grunt, Gulp) , various UI Frameworks including AngularJS , Knockout JS , and CSS Frameworks including Bootstrap, and Foundation. He is adaptable to new technologies and frameworks. He is a rigorous, quality-conscious contributor with solid analytical skills. I can also be found on youtube - Youtube Channel: https://www.youtube.com/user/akuong/

Leave a comment