java runtime_error ai_generated true

java.util.ConcurrentModificationException

ID: java/concurrentmodificationexception

Also available as: JSON · Markdown
92%Fix Rate
94%Confidence
80Evidence
2023-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
17 active

Root Cause

ConcurrentModificationException is thrown when a collection is structurally modified while being iterated, either from the same thread (modifying during for-each loop) or from another thread without proper synchronization.

generic

Workarounds

  1. 95% success Use Iterator.remove() for single-threaded removal during iteration, or use Collection.removeIf() for predicate-based removal
    1. For removing elements while iterating: replace the for-each loop with an explicit Iterator and call iterator.remove(). 2. For simpler cases, use collection.removeIf(predicate) which handles the iterator internally. 3. For adding elements during iteration, copy the collection first: new ArrayList<>(original) and iterate over the copy while modifying the original.
  2. 90% success Use ConcurrentHashMap or CopyOnWriteArrayList for multi-threaded access
    1. For Map: replace HashMap with ConcurrentHashMap. Its iterators are weakly consistent and never throw ConcurrentModificationException. 2. For List with mostly reads: replace ArrayList with CopyOnWriteArrayList. It creates a fresh copy on every write, so iterators see a snapshot. 3. For List with frequent writes: use synchronized blocks around iteration or ConcurrentLinkedDeque for queue-like access patterns. 4. For Stream operations, use parallelStream() with thread-safe collectors instead of manual iteration.

Dead Ends

Common approaches that don't work:

  1. Wrapping the collection with Collections.synchronizedList() and iterating without external synchronization 75% fail

    Collections.synchronizedList() only synchronizes individual method calls. Iteration requires holding the lock for the entire duration of the loop. Without a synchronized block around the entire iteration, another thread can modify the list between hasNext() and next() calls.

  2. Using collection.remove() inside a for-each loop instead of iterator.remove() 95% fail

    The enhanced for-each loop uses an iterator internally. Calling collection.remove() modifies the collection's modCount without updating the iterator's expectedModCount, which triggers the ConcurrentModificationException on the next iterator operation.

Error Chain

Leads to:
Preceded by:
Frequently confused with: