I ran into a ConcurrentModificationException (CME) during stress testing.
What does CME actually mean?
It means that you’ve updated your Collection while you’ve been iterating over it (usually in a multi-threaded fashion, but it can occur in a single thread that updates while iterating).
A few more things to know about CME:
Best effort detection - If you see a CME printout, first off, consider yourself lucky, CMEs are thrown only in best effort. In another universe, the concurrent modification would not have been detected, causing your collection to become corrupted, instead of fast-failing with a CME.
IDing the problem – Like deadlocks, CME’s are easy to pinpoint once you inspected the exception’s stack trace.
Getting around it:
- ListIterator
If you’re single threaded, consider solving the CME by manipulating the collection via the ListIterator interface instead of directly.
Advantages – simple.
Drawbacks – suitable for a single thread model. - Synchronizers
Use locks to obtain mutual exclusion while doing collection R/W operations.
Advantages – easy to code.
Drawbacks – lock overhead for reading operations. - Copy-on-write
Take advantage of the Java.util.concurrent collections like: CopyOnWriteArrayList, CopyOnWriteArraySet. If you require a map then grab CopyOnWriteMap from Apache (this guys have been doing Sun’s dirty work for years now).
Advantages – very good reading performance (no locks are used, visibility is obtained via volatility).
Drawbacks – very bad write performance on large maps.
Conclusion – use for seldom mutating collections. - Concurrent Collections
If you want to go heavyweight, consider using: ConcurrentHashMap (or one of its package friends).
Once you create an iterator over a ConcurrentHashMap, it does not freeze the collection for traversal, updates to the collection may or may not appear during the traversal (weakly consistent).
The approach I ended up taking:
My use case was populating an almost never changing ~ten items cache. A copyonwrite map was the best choice, I believe.

One new serviceability artifact that I have long ago really wanted to have in production was the verbose GC, this feature records the JVM garbage collection activity over time, providing insight for resolving issues such as: stop-the-world performance freezes, memory leaks, native heap corruption, etc.
A trigger for action
Via e-mail