The ConcurrentModificationException
is a very common exception in Java that occurs usually while working with Collections. The ConcurrentModificationException
is used to fail-fast when something being iterated on is modified.
This exception occurs when an object is attempted to be modified concurrently without permission. For example, if a Collection
is modified while a thread is traversing it using an Iterator
, a ConcurrentModificationException
is thrown from the Iterator.next()
method.
The ConcurrentModificationException
can occur in both multithreaded and single-threaded environments.
 
What Causes ConcurrentModificationException
The ConcurrentModificationException
generally occurs when working with Java Collections. The Collection
classes in Java are very fail-fast and if they are attempted to be modified while a thread is iterating over it, a ConcurrentModificationException
is thrown.
This exception can occur in both multithreaded and single-threaded Java environments. Here are examples of each:
- Multithreaded environment - If a thread is traversing over a
Collection
using anIterator
and another thread attempts to add or remove elements to theCollection
. - Single-threaded environment - When an element is attempted to be removed from an
ArrayList
using theremove()
method while it is being traversed using an enhancedfor
loop.
 
ConcurrentModificationException Example
Here is an example of a ConcurrentModificationException
thrown when attempting to remove an element from an ArrayList
using the remove()
method while traversing it using an enhanced for
loop:
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModificationExceptionExample {
public static void main(String args[]) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for (String elem : list) {
if (elem.equals("a")) {
list.remove(elem);
}
}
}
}
Since the enhanced for
loop uses an Iterator
internally to traverse elements in a Collection
, running the above code causes a ConcurrentModificationException
since the remove()
method of the Collection
is used instead of the iterator:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at ConcurrentModificationExceptionExample.main(ConcurrentModificationExceptionExample.java:12)
 
How to Resolve ConcurrentModificationException
The above exception can be resolved by traversing the elements of the ArrayList
using a traditional for
loop instead of the enhanced for
loop. Since the traditional for
loop does not use an Iterator
to traverse the elements of a Collection
, it does not cause a ConcurrentModificationException
:
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModificationExceptionExample {
public static void main(String args[]) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("a")) {
list.remove(list.get(i));
}
}
System.out.println(list);
}
}
Since the ConcurrentModificationException
belongs to the Iterator
and not the remove()
method of the ArrayList
, running the above code will produce the correct output as expected:
[b, c, d]
The above exception can also be resolved by using an Iterator
to traverse the elements of the ArrayList
and using the Iterator.remove()
method to remove elements. Alternatively, the Collection.removeIf()
method introduced in Java 8 can be used to remove an element from a Collection
if a given condition is true.
 
How to Avoid ConcurrentModificationException in Multithreaded Environments
To avoid the ConcurrentModificationException
in multithreaded environments, certain precautions can be used:
- Iterating over an array instead of a collection - this can work well with small-sized lists but can degrade performance for larger ones.
- Locking the collection by placing it in a
synchronized
block - this may not be the most effective approach as it does not utilize the very purpose of multi-threading. - Using Java concurrent collections such as
ConcurrentHashMap
andCopyOnWriteArrayList
classes can help avoid theConcurrentModificationException.
 
Track, Analyze and Manage Errors with Rollbar
Fixing Errors in your Java code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring, tracking and triaging, making fixing Java errors easier than ever. Sign Up Today!