About Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.

The ConcurrentModificationException is a RuntimeException that may be thrown by methods that have detected concurrent modification of an object, when such modification is not permissible. An example of not permissible behavior is when a thread tries to modify the internal structure of a Collection, while another thread is iterating over it.

In general, the results of the iteration are undefined. Some iterators throw a ConcurrentModificationException when they detect such behavior. These iterators are called fail-fast iterators, as they stop the normal execution to report an error, rather that continuing in a non-deterministic way. Notice that this exception does not indicate that the object has been concurrently modified by a different thread. The exception is thrown even one thread is violating an object’s contract.

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
at java.util.HashMap$KeyIterator.next(HashMap.java:960)
at main.java.Example.main(Example.java:18)

The exception is thrown because we change the internal structure of the HashMap by removing an existing key, while we iterating over it.

Case 2: After the creation of an iterator, the Collection is internally modified by any method other than the iterator’s own methods for removal and addition.

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at main.java.Example.main(Example.java:25)

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at main.java.Example.main(Example.java:28)

2. Deal with the exception

First of all, we must understand how Java decides that a collection is modified concurrently and a ConcurrentModificationException must be thrown. In Java 7, the implementation of the ArrayList uses the following field, to provide a fail-fast iterator:

protected transient int modCount;

Following the same logic, the implementation of the HashMap uses the following field:

transient int modCount;

In both implementations, the modCount field indicates the number of times the collection has been structurally modified. For example, a structural modification can be an operation that changes the number of mappings in a HashMap, or an operation that changes the size of an ArrayList.

Synchronization

In order to avoid more than one threads accessing or modifying the same object, you can synchronize them over the object, in order to allow only one thread to manipulate it over the time. However, notice that this approach may reduce the performance of your application, or create deadlocks, if the application has not been developed carefully.

Synchronized Collections

In addition to their default implementations, Java provides a synchronized implementation of a Map, a List, a Set, a Collection, etc. through the Collections class. Moreover, Java provides the CopyOnWriteArrayList class, in which all mutative operations are implemented by making a fresh copy of the underlying array. Finally, Java also provides the ConcurrentHashMap class, which offers full concurrency of retrievals and adjustable expected concurrency for updates.

All referenced implementations are thread safe. However, the usage of such data structures may also reduce the performance of your application, as thread synchronization spends CPU cycles.

To conclude, all aforementioned methods aim to eliminate the ConcurrentModificationException. However, in a multi-threaded environment this elimination usually comes with the cost of thread synchronization. In any case, each application has its own specifications and requirements and thus, a meticulous design and implementation are very important in order for such exceptions to be eliminated.

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.