ConcurrentModificationException in Java
When an object is attempted to be updated concurrently when it is not allowed, the ConcurrentModificationException arises. This error typically occurs while using Java Collection classes.
When another thread is iterating over a Collection, no thread may edit that Collection. This is because with each iteration, the outcome gets more uncertain. This error is thrown by some Iterator class implementations, including all of the general-purpose Iterator implementations offered by the JRE. These iterators are known as fail-fast because they instantly throw an exception if they run into a problem rather than having to deal with the collection's unpredictable behaviour in the future.
This exception need not be raised every time another thread tries to make changes to a Collection object. It may also occur if a single thread calls several methods that attempt to break the object's contract. This could occur if a thread tries to edit a collection object while the collection is being iterated by a fail-fast iterator, in which case the iterator will throw an exception.
Concurrentmodificationexception.java
import java.awt.List;
import java.util.*;
public class Concurrentmodificationexception {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(9);
list.add(5);
list.add(10);
list.add(6);
list.add(3);
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer value = it.next();
System.out.println("List Value:" + value);
if (value.equals(10))
list.remove(value);
}
}
}
Output:

Explanation:
According to this message, the exception is thrown when the next method is called because the list is being iterated by the iterator while we are simultaneously making changes to it. However, if we apply the changes shown below to the hashmap, it won't raise an exception since the hashmap's size won't change.
Concurrentmodificationexception.java
import java.awt.List;
import java.util.*;
public class Concurrentmodificationexception {
public static void main(String[] args) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(1, 6);
map.put(2, 4);
map.put(3,9);
Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()) {
Integer key = it.next();
System.out.println("Value of the Map:" + map.get(key));
if (key.equals(2)) {
map.put(3, 4);
}
}
}
}
Output:

Explanation:
This example is perfect since the size of the map stays constant as the iterator iterates over it. In the if statement, just the map is being updated.
Constructors of ConcurrentModificationException
There are 4 different types of ConcurrentModificationException constructors. –
- public ConcurrentModificationException(): This generates a ConcurrentModificationException with no parameters.
- public ConcurrentModificationException(String message): ConcurrentModificationExceptions are produced as a result, each with a descriptive message describing the exception.
- public ConcurrentModificationException(Throwable cause): This generates a ConcurrentModificationException with the message (cause==null?null:cause.toString()) and the cause (cause==null?null). The Throwable later determines the cause. getCause().
- public ConcurrentModificationException(String message, Throwable cause): A ConcurrentModificationException is produced as a result, complete with a cause and descriptive message. (cause==null?null:cause.toString()). Throwable later gets the message back. Throwable will eventually obtain the results of getMessage() and cause. getCause().
How can ConcurrentModificationException be prevented in a multi-threaded environment?
In a multi-threaded system, the ConcurrentModificationException can be avoided by doing the following:
- We may iterate over the array rather than the collection class. In this method, we can work extremely efficiently with small lists, but if the array size is too huge, the performance will suffer.
- The list might also be locked by including it in the synchronised block. This strategy is useless since it defeats the primary goal of employing multi-threading.
- Classes for ConcurrentHashMap and CopyOnWriteArrayList will be included in JDK 1.5 or above. We can prevent concurrent modification exceptions with the use of these classes.
How can ConcurrentModificationException be prevented in a context with only single thread?
You may remove an item from an underlying collection object by using the remove() method of an iterator.
To remove an element from an underlying collection object, use the iterator's remove() function. However, in this instance, just that specific object may be deleted from the list. Let's use Concurrent Collection classes to execute an example.
ConcurrentModificationException.java
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentModificationException {
public static void main(String[] args) {
List<String> myList = new CopyOnWriteArrayList<String>();
myList.add("2");
myList.add("4");
myList.add("6");
myList.add("8");
myList.add("10");
Iterator<String> it = myList.iterator();
while (it.hasNext()) {
String value = it.next();
System.out.println("List Value:" + value);
if (value.equals("8")) {
myList.remove("4");
myList.add("6");
myList.add("7");
}
}
System.out.println("List Size:" + myList.size());
Map<String, String> myMap = new ConcurrentHashMap<String, String>();
myMap.put("1", "1");
myMap.put("2", "2");
myMap.put("3", "3");
Iterator<String> it1 = myMap.keySet().iterator();
while (it1.hasNext()) {
String key = it1.next();
System.out.println("Map Value:" + myMap.get(key));
if (key.equals("1")) {
myMap.remove("3");
myMap.put("4", "4");
myMap.put("5", "5");
}
}
System.out.println("Map Size:" + myMap.size());
}
}
Output:
