Java | Concept of Fail Fast and Fail Safe Iterators

|
| By Webner

The terms Fail Fast and Fail Safe iterators come into picture when we deal with Concurrency issue while programming in Java. In Java, while iterating over a collection if multiple threads modify the collection (such as adding a new element, deleting an element or updating the value of an element) – this situation is called Concurrent Modification.

So, what are Fail Fast and Fail Safe Iterators?

Fail Fast Iterator:

Fail fast iterator works directly on the structure of the collection and immediately throws ConcurrentModificationException while iterating through it if there is a structural modification of the collection inside the loop. Thus, in an apparent situation of concurrent modification, the iterator fails quickly and cleanly, rather than showing unexceptional behavior at any time in the future. It can throw the ConcurrentModificationException in two scenario, i.e. Single Threaded Environment and Multiple Threaded Environment. In both the situations, anything which can lead to the modification of the structure, will result into ConcurrentModificationException. Iterators from Java Collection classes, for example, HashSet, ArrayList and Vector fall under category of fail-fast iterators.

However, we can’t totally rely upon the Fail Fast behavior of an Iterator because the iterator throws the exception on best-effort basis. That is why, this behavior can only be used while detecting bugs.

For Example:

import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
public class ExampleFailFast {
public static void main(String[] args) {
Map < String, String > books = new HashMap < String, String > ();
books.put("Java", "Complete Reference");
books.put("C++", "Let Us C++");
Iterator iterator = books.keySet().iterator(); //iterating over the list
while (iterator.hasNext()) {
System.out.println(books.get(iterator.next()));
books.put("DBMS", "Database Concepts");
}
}
}

Output:

Complete Reference
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at ExampleFailFast.main(ExampleFailFast.java:19)

Fail Safe Iterator:

Fail Safe Iterator works in exactly opposite way of Fail Safe Iterator where it first makes a copy of the original collection and then iterates over it rather than iterating over the original structure of the collection. Hence, it doesn’t detect any change in the original data structure and works with stale values without throwing ConcurrentModificationException. Once changes are made modified data is copied back into the original collection. Iterators returned by concurrent collection classes such as CopyOnWriteArrayList or CopyOnWriteArraySet fall in the category of fail-safe iterators.

However, there are few drawbacks to using Fail Safe Iterators. Such as:

Fail safe iterators do not guarantee that the data being read is the data currently in the original data structure.
It is an overhead to maintain the copied data structure in memory as it may lead to the memory issues later on.

For Example:

import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
public class ExampleFailSafe {
public static void main(String[] args) {
ConcurrentHashMap < String, String > books = new ConcurrentHashMap < String, String > ();
books.put("Java", "Complete Reference");
books.put("C++", "Let Us C++");
Iterator iterator = books.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(books.get(iterator.next()));
books.put("DBMS", "Database Concepts");
}
}
}

Output:

Complete Reference
Let Us C++

Leave a Reply

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