BackendBench
Coffee

Home โ€บ Java exceptions โ€บ ConcurrentModificationException

Unchecked exception ยท java.util

ConcurrentModificationException: causes and fixes

A collection was structurally modified while it was being iterated.

What it looks like

java.util.ConcurrentModificationException

Extends RuntimeException in java.util.

What it means

Most collections return fail-fast iterators. If the collection changes (an add or remove, not a mere set) after the iterator was created, and not through that iterator, the next call to next() throws ConcurrentModificationException. Despite the name it happens in single-threaded code too, the classic case being a for-each loop that removes from the list it is looping over.

Common causes

How to fix it

  1. Use list.removeIf(predicate) or map.entrySet().removeIf(...).
  2. Remove through the Iterator: it.remove().
  3. Iterate over a copy when the loop body must change the original: new ArrayList<>(list).
  4. For real concurrency use ConcurrentHashMap or CopyOnWriteArrayList, or synchronise access.

Broken and fixed

fails
for (String s : names) {
    if (s.isEmpty()) names.remove(s); // throws on the next iteration
}
works
names.removeIf(String::isEmpty);

๐Ÿ”Ž Unravel the failing code ๐Ÿ”Ž Unravel the fix

In Spring and enterprise code

The fail-fast check is best effort and is not a thread-safety guarantee; do not rely on catching it. Shared state in singleton Spring beans is a typical source of the multi-threaded variant.

Debug it faster

Paste the whole stack trace into the stack trace beautifier to hide framework frames, jump to the root cause and find the first line of your own code. It runs in your browser, so the trace never leaves your machine.

Frequently asked questions

Is ConcurrentModificationException a checked or unchecked exception?

ConcurrentModificationException is an unchecked exception (it extends RuntimeException), so you are not forced to catch it. Prevent it with validation, or handle it where the input enters the system.

Which package is ConcurrentModificationException in?

It lives in java.util, so the import is import java.util.ConcurrentModificationException;.

What is the first thing to check when I see ConcurrentModificationException?

Read the message and the first stack trace line in your own code. The usual causes are: Removing or adding to a list inside a for-each loop over that same list; and One thread modifying a non-thread-safe collection while another iterates it.

Related exceptions

More tools you might need