← Back to Java

Fail-fast vs Fail-safe Iterators

JavaMidjava

The Question

What is the difference between fail-fast and fail-safe iterators?

What a Strong Answer Covers

  • fail-fast = ConcurrentModificationException on modification
  • operates on original
  • modCount
  • ArrayList/HashMap
  • fail-safe = no exception works on copy
  • CopyOnWriteArrayList/ConcurrentHashMap
  • more memory overhead

Senior-Level Answer

The terms fail-fast and fail-safe describe how iterators behave when the underlying collection is modified during iteration.

**Fail-fast iterators** throw `ConcurrentModificationException` if the collection is structurally modified (elements added or removed) after the iterator is created, by any means other than the iterator's own `remove()` method. They detect modification by checking a `modCount` field on the collection against a count captured when the iterator was created. If they differ, the exception is thrown on the next `next()` or `hasNext()` call.

Fail-fast iterators are used by most standard `java.util` collections: `ArrayList`, `HashMap`, `HashSet`, `LinkedList`. They are not a thread-safety guarantee — the exception is a best-effort notification. The Java documentation explicitly states that fail-fast behavior should not be relied upon for program correctness; it is designed to detect programming bugs, not as a concurrency mechanism.

**Fail-safe iterators** work on a snapshot or copy of the collection as it existed when iteration began. Modifications to the original collection during iteration are not visible to the iterator and do not cause exceptions. The tradeoff is that the iterator may not reflect the current state of the collection.

Fail-safe iterators are used by `java.util.concurrent` classes: `ConcurrentHashMap` (iterator reflects current state via a weakly consistent traversal), `CopyOnWriteArrayList` (iterates over a snapshot of the array taken at iterator creation time — true copy semantics).

`CopyOnWriteArrayList` is appropriate for read-heavy workloads with infrequent writes — each write copies the entire array, which is expensive but produces a pristine read path with no locking. `ConcurrentHashMap`'s iterators are weakly consistent, meaning they may or may not reflect updates that occur after iteration begins.

For interviews: `ArrayList` → fail-fast; `CopyOnWriteArrayList` → fail-safe (copy). Be precise about weakly consistent iterators in `ConcurrentHashMap`.

Key Differences

AspectFail-FastFail-Safe
On modificationThrows ConcurrentModificationExceptionNo exception — iterates over copy/snapshot
Detection mechanismmodCount comparisonOperates on copy or weakly consistent view
Reflects live data?Yes, until modificationNo (copy) or partially (weakly consistent)
Memory overheadLowHigher (copy of collection)
ExamplesArrayList, HashMap, HashSetCopyOnWriteArrayList, ConcurrentHashMap
Thread-safe?No — exception is best-effortYes — designed for concurrent use

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly defines both types, explains ConcurrentModificationException, and names at least one concrete example of each.

3/3 — Strong Answer

Also explains the modCount mechanism, the snapshot/copy strategy, the memory cost of CopyOnWriteArrayList, and the weakly consistent distinction for ConcurrentHashMap.

Common Mistakes

  • Treating ConcurrentModificationException as a guarantee of thread safety — it is a best-effort check, not a concurrency mechanism.
  • Thinking fail-safe iterators always reflect the current state — CopyOnWriteArrayList iterators see a frozen snapshot, not live updates.
  • Recommending CopyOnWriteArrayList for write-heavy workloads — copying the entire array on every write is expensive.

Follow-Up Questions

  • Why can you safely remove from an ArrayList during iteration using iterator.remove(), but not list.remove()? — iterator.remove() updates the iterator's internal modCount to match; list.remove() does not, causing the next iterator check to throw.
  • What is weakly consistent iteration in ConcurrentHashMap? — The iterator may or may not reflect elements inserted or removed after iteration started; it never throws CME and processes each element at most once.
  • When is CopyOnWriteArrayList the right choice? — Read-heavy workloads where writes are rare; traversal is the dominant operation; iteration must never throw CME.

Related Questions

  • JVM vs JRE vs JDK
  • Java Platform Independence
  • How JVM Works
  • Main Features of Java
  • public static void main

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout