C

Core Java tutorial for beginners

Clean • Professional

Fail-Fast vs Fail-Safe Iterators in Java – Complete Guide with Examples

3 minute

Fail-Fast vs Fail-Safe Iterators in Java

Iterators in Java behave differently when the underlying collection is modified during iteration. This difference creates two important types:

learn code with durgesh images

  • Fail-Fast Iterators
  • Fail-Safe Iterators

Understanding these behaviors is very important for interviews and real-world multithreaded applications.


Fail-Fast Iterators

A Fail-Fast Iterator immediately throws a ConcurrentModificationException if the collection is structurally modified during iteration (other than using iterator.remove()).

Found In (Non-Concurrent Collections)

Fail-fast iterators are used in normal Java collections:

  • ArrayList
  • LinkedList
  • HashSet
  • LinkedHashSet
  • TreeSet
  • HashMap (via keySet(), values(), entrySet())
  • LinkedHashMap
  • TreeMap
  • Vector (modern iterator)

These belong to the java.util package.


How Fail-Fast Works Internally

Fail-fast iterators use two variables:

  • modCount → tracks structural changes in the collection
  • expectedModCount → value stored by iterator at the start

When iterating:

If (modCount != expectedModCount)
    throw ConcurrentModificationException

So any structural modification during iteration breaks synchronization and throws an exception.


Fail-Fast Example (Throws Exception)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        for (String s : list) {
            if (s.equals("B")) {
                list.remove(s);  // Structural modification
            }
        }
    }
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException

How to Use Fail-Fast Safely

Use iterator.remove(), not list.remove():

Iterator<String> it = list.iterator();

while (it.hasNext()) {
    String s = it.next();
    if (s.equals("B")) {
        it.remove(); // Safe
    }
}

This avoids fail-fast exception because removal happens through the iterator itself.


Characteristics of Fail-Fast

  • Throws ConcurrentModificationException
  • Faster (no copy is created)
  • Not thread-safe
  • Unsafe during concurrent modifications
  • Used in almost all non-concurrent collections

2. Fail-Safe Iterators

A Fail-Safe Iterator does not throw exceptions even if the collection is modified during iteration.

Why?

Because it works on a copy (snapshot) of the underlying collection.


Found In (Concurrent Collections)

Fail-safe iterators come from the java.util.concurrent package:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet
  • ConcurrentSkipListMap
  • ConcurrentSkipListSet

These collections are designed for multithreading.


How Fail-Safe Works Internally

  • Creates a clone or snapshot copy of the collection
  • Iterator works on the copy, not the original
  • Original collection can be safely modified during iteration
  • Does not throw ConcurrentModificationException
  • Changes made during iteration are NOT visible to the iterator

Fail-Safe Example (No Exception)

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        list.add("A");
        list.add("B");

        for (String s : list) {
            list.add("C");  // No exception
        }

        System.out.println(list);
    }
}

Output:

[A, B, C, C]

Characteristics of Fail-Safe

  • No ConcurrentModificationException
  • Safe in multi-threaded environments
  • Allows modification during iteration
  • Slower due to copying
  • The iterator does not reflect new changes
  • Thread-safe

Fail-Fast vs Fail-Safe Iterators

FeatureFail-Fast IteratorFail-Safe Iterator
Works onOriginal collectionCopy of collection
Throws exception?Yes, ConcurrentModificationExceptionNo
SafetyNot thread-safeThread-safe
PerformanceFasterSlower (due to copy)
Used inNormal CollectionsConcurrent Collections

Diagram: Fail-Fast vs Fail-Safe

Fail-Fast

Original Collection
       ↓
 Iterator (checks modCount)
       ↓
Modification → Exception

Fail-Safe

Original Collection → Snapshot Copy
                          ↓
                       Iterator
        (Modifications allowed, no exception)

Points to Remember

  • Fail-Fast = checks modification immediately
  • Fail-Safe = works on duplicate copy
  • Fail-Fast is common in List, Set, Map
  • Fail-Safe is common in Concurrent collections
  • Using iterator.remove() prevents fail-fast errors
  • Fail-Fast is not guaranteed — it is “best-effort

Article 0 of 0