Why is a ConcurrentModificationException thrown and how to debug it
A ConcurrentModificationException is thrown when elements in a Collection are modified concurrently by multiple threads or when the structure of the collection is altered during an iteration. Avoid the exception by using the Iterator's remove() or utilize thread-safe variants when in a concurrent environment.
Defining ConcurrentModificationException
The ConcurrentModificationException stems from the fail-fast behavior of Java collections' iterators, signifying an unexpected structural adjustment not done through the iterator's own methods. Multi-threading adds complexity, thus synchronization is imperative.
Countermeasures to the exception
- Harness thread-safe Java Collections, for instance, ConcurrentHashMap.
- Enforce synchronization when handling collections in a multi-threaded environment.
- For concurrent bonanzas, employ CopyOnWriteArrayList or similar classes.
Best practices and advanced techniques
Even concurrent collections like ConcurrentHashMap can sling a ConcurrentModificationException if improperly used. Here are some tactics to stay clear of it.
Safe modifications during iteration
- Put Java 8's removeIf and Predicate to use for safe element eviction during iteration.
- Introduce accurate locking and synchronization in multi-threaded access scenarios.
- In the debugging stage, scan the stack trace to pinpoint the birthplace of the ConcurrentModificationException.
- Confine the scope of the collection references to curb surprise modifications.
Hibernate and DB related concurrency
- With Hibernate, use versioning for an exclusive row-wise DB access.
- Tweak the isolation level to shun dirty reads which might be the root cause.
- Carefully manage concurrent DB updates and deletions to prevent data integrity issues leading to ConcurrentModificationExceptions.
Iterator types and thread safety
- Employ fail-safe iterators, as provided by ConcurrentHashMap.
- Note that fail-fast iterators are built for bug detection. An undetected modification is not a licence to assume absence of a ConcurrentModificationException.
Was this article helpful?