Difference between Fail Fast and Fail Safe in Java ?

Fail-Fast and Fail-Safe are two approaches that Java collections use to handle concurrent modifications when iterating over elements. Here’s an in-depth comparison between the two with examples to illustrate their behavior.

Fail-Fast Iterator

A fail-fast iterator immediately throws a ConcurrentModificationException if a collection is modified structurally after the iterator is created (except through the iterator itself). Fail-fast iterators operate directly on the collection and detect changes by checking a modification count.

  • Characteristics:
  • Directly iterates over the collection.
  • Throws ConcurrentModificationException if the collection is structurally modified (addition or removal of elements) after the iterator’s creation.
  • Example collections: ArrayList, HashMap, HashSet.

Example of Fail-Fast Iterator

import java.util.ArrayList;
import java.util.Iterator;

public class FailFastExample {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>(List.of(1, 2, 3, 4));

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
            list.add(5); // Modifying the collection while iterating
        }
    }
}

Output:

1
Exception in thread "main" java.util.ConcurrentModificationException

In this example:

  • The iterator is traversing the ArrayList, but when we try to add an element during iteration, the mod count is updated in the ArrayList.
  • The iterator detects this structural modification and throws a ConcurrentModificationException.

Fail-Safe Iterator

A fail-safe iterator operates on a copy (or snapshot) of the collection’s data, meaning any structural modifications to the collection will not affect the iterator. It does not throw ConcurrentModificationException if the collection is modified while being iterated, but changes won’t reflect in the iteration process.

  • Characteristics:
  • Iterates over a clone or snapshot of the collection.
  • Does not throw ConcurrentModificationException if the collection is modified during iteration.
  • Allows safe concurrent access but comes with extra memory overhead.
  • Example collections: CopyOnWriteArrayList, ConcurrentHashMap.

Example of Fail-Safe Iterator

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeExample {
    public static void main(String[] args) {
        CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(new Integer[]{1, 2, 3, 4});

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
            list.add(5); // Modifying the collection while iterating
        }

        System.out.println("Final List: " + list);
    }
}

Output:

1
2
3
4
Final List: [1, 2, 3, 4, 5, 5, 5, 5]

In this example:

  • The iterator works on a snapshot of the collection. Any modification made during iteration (like adding 5 in this case) is not reflected in the current iteration process.
  • The modification (addition of 5) is made on the original collection, but the iterator safely completes the iteration over the initial snapshot.

Key Differences Between Fail-Fast and Fail-Safe

FeatureFail-FastFail-Safe
BehaviorThrows ConcurrentModificationException on modificationContinues iteration without exception
Working MechanismIterates directly over the collectionIterates over a clone/snapshot of the collection
Concurrent AccessNot suitable for concurrent accessSuitable for concurrent access
Memory OverheadNo extra memory usageAdditional memory for snapshot/clone
ExamplesArrayList, HashMap, HashSetCopyOnWriteArrayList, ConcurrentHashMap

When to Use Fail-Fast and Fail-Safe

  • Fail-Fast: Use in single-threaded environments where detecting unintended concurrent modifications is crucial. It helps avoid unpredictable results when iterating through collections.
  • Fail-Safe: Use in concurrent applications where collections may be modified by multiple threads. They ensure safe, concurrent access without exceptions but may incur additional memory overhead.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *