Introduction
ConcurrentModificationException in Java is a runtime exception that occurs when a collection is modified while iterating over it with methods that are not fail-safe.
Table of Contents
- What is ConcurrentModificationException?
- Common Causes
- How to Avoid ConcurrentModificationException
- Examples
- Conclusion
1. What is ConcurrentModificationException?
ConcurrentModificationException is thrown when a thread attempts to modify a collection while another thread is iterating over it, or when the iteration structure is altered unexpectedly.
2. Common Causes
- Modifying a collection directly (e.g., adding or removing elements) while iterating with an iterator.
- Concurrent modifications by multiple threads on the same collection.
3. How to Avoid ConcurrentModificationException
- Use the Iterator‘sremove()method to safely remove elements during iteration.
- Use concurrent collections like CopyOnWriteArrayListorConcurrentHashMapfor multi-threaded environments.
- Avoid structural modifications during iteration.
4. Examples
Example 1: Causing ConcurrentModificationException
This example demonstrates a scenario that leads to ConcurrentModificationException.
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModificationExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        for (String item : list) {
                list.remove(1); // This will cause ConcurrentModificationException
        }
    }
}
Output:
 Exception in thread "main" java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1095)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1049)
	at net.javaguides.utility.ConcurrentModificationExample.main(ConcurrentModificationExample.java:13)
Example 2: Avoiding ConcurrentModificationException with Iterator
This example shows how to avoid ConcurrentModificationException by using an 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<>();
        list.add("A");
        list.add("B");
        list.add("C");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if ("B".equals(item)) {
                iterator.remove(); // Safely removing element using iterator
            }
        }
        System.out.println("List after removal: " + list);
    }
}
Output:
List after removal: [A, C]
Example 3: Using CopyOnWriteArrayList to Avoid Issues
This example demonstrates how to use CopyOnWriteArrayList to prevent ConcurrentModificationException.
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        for (String item : list) {
            if ("B".equals(item)) {
                list.remove(item); // No ConcurrentModificationException here
            }
        }
        System.out.println("List after removal: " + list);
    }
}
Output:
List after removal: [A, C]
5. Conclusion
ConcurrentModificationException is a common issue when working with collections in Java, especially in multi-threaded environments. By using safe practices such as the Iterator‘s remove() method or concurrent collections, you can avoid this exception and ensure your code runs smoothly.