ConcurrentModificationException in Java


ConcurrentModificationException is a runtime exception in Java that arises when multiple threads try to modify a collection at the same time. In this blog, we’ll explore what ConcurrentModificationException is, the scenarios in which it occurs, and how to prevent it in Java programs.

1. What is ConcurrentModificationException?

ConcurrentModificationException is an exception that occurs when you attempt to modify a collection (e.g., ArrayList, HashMap, HashSet) while another thread is concurrently iterating over it. This exception indicates that the collection’s structural modification and its iteration are not synchronized, leading to data inconsistencies and potential errors.

2. When ConcurrentModificationException Arises

1. Simultaneous Iteration and Modification: This exception occurs when one thread is iterating over a collection (e.g., using an Iterator or enhanced for loop), and another thread tries to add, remove, or modify elements within the same collection.

List<String> names = new ArrayList<>();
names.add("Sagar");
names.add("Pradnya");

Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
    String name = iterator.next();
    if (name.equals("Pradnya")) {
        // Concurrent modification by another thread
        names.remove(name);
    }
}

2. Using Non-thread-safe Collections: ConcurrentModificationException can also happen when you use non-thread-safe collections without proper synchronization. These collections are not designed for concurrent access and can lead to unpredictable behavior when multiple threads access them simultaneously.

3. Preventing ConcurrentModificationException

To prevent ConcurrentModificationException and ensure safe concurrent access to collections, you can follow these strategies:

1. Use Thread-safe Collections: Whenever possible, use thread-safe collections provided by Java’s java.util.concurrent package. Classes like CopyOnWriteArrayList, ConcurrentHashMap, and ConcurrentLinkedQueue are designed for concurrent access and modify their internal structures to prevent concurrent modification issues.

2. Synchronization: If you must use non-thread-safe collections, ensure proper synchronization by using synchronized blocks or methods to control access to the collection. This involves wrapping the collection modifications inside synchronized blocks.

List<String> names = new ArrayList<>();
names.add("Sagar");
names.add("Pradnya");

synchronized (names) {
    Iterator<String> iterator = names.iterator();
    while (iterator.hasNext()) {
        String name = iterator.next();
        if (name.equals("Pradnya")) {
            iterator.remove(); // Safely remove elements
        }
    }
}

3. Use Iterator’s Remove Method: If you need to remove elements from a collection while iterating over it, use the remove method provided by the Iterator itself. This method ensures that the collection is modified in a way that is safe for concurrent access.

List<String> names = new ArrayList<>();
names.add("Sagar");
names.add("Pradnya");

Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
    String name = iterator.next();
    if (name.equals("Pradnya")) {
        iterator.remove(); // Safely remove elements using iterator
    }
}

4. Immutable Collections: Consider using immutable collections where the data is read-only. Immutable collections cannot be modified once created, making them safe for concurrent access without the risk of ConcurrentModificationException.

List<String> names = Collections.unmodifiableList(
			new ArrayList<>(Arrays.asList("Sagar", "Pradnya"))
			);

5. Concurrency Control: If you have complex scenarios with concurrent data modification, consider using more advanced concurrency control mechanisms like locks, semaphores, or the java.util.concurrent framework’s classes, such as ReentrantLock.

Related Post: Java ReentrantLock Example

4. Summary

ConcurrentModificationException is a common challenge in multi-threaded Java applications. By understanding its causes and following best practices, you can ensure that your code is resilient to concurrent modifications. Whether it’s using thread-safe collections, proper synchronization, or the Iterator’s remove method, there are various strategies to keep your Java programs free from this exception and maintain data integrity in concurrent environments.

5. References

  1. Java ReentrantLock Example
  2. Class ConcurrentModificationException – JavaDoc

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.