Fail-Fast iterators immediately throw ConcurrentModificationException if a collection is modified while iterating over it.
Fail-Safe iterators don't throw any exceptions if a collection is modified while iterating over it because it operates on the clone of the collection, not on the actual collection.
Fail-Fast Iterators In Java :
Fail-Fast iterators, returned by most of the collection types, doesn't tolerate any structural modifications to a collection while iterating over it. (Structural modifications means add, remove or updating an element in the collection) It throws ConcurrentModificationException if a collection is structurally modified while iteration is going on the collection. But, it doesn't throw any exceptions if the collection is modified by the iterator's own methods like remove().
How Fail-Fast Iterators Work?
All Collection types maintain an internal array of objects ( Object[] ) to store the elements. Fail-Fast iterators directly fetch the elements from this array. They always consider that this internal array is not modified while iterating over its elements. To know whether the collection is modified or not, they use an internal flag called modCount which is updated each time a collection is modified. Every time when an Iterator calls the next() method, it checks the modCount. If it finds the modCount has been updated after this Iterator has been created, it throws ConcurrentModificationException.
Fail-Safe Iterators In Java :
Fail Safe Iterator makes copy of the internal data structure (object array) and iterates over the copied data structure.Any structural modification done to the iterator affects the copied data structure. So, the original data structure remains structurally unchanged. Hence, no ConcurrentModificationException is thrown by the fail safe iterator. The may result in reading stale data, since the data in the map is snapshot of what was copied at the time of creation.
The differences can be summarized as follows:
Fail Fast Iterator | Fail Safe Iterator | |
---|---|---|
Throw ConcurrentModification Exception | Yes | No |
Clone object | No | Yes |
Memory Overhead | No | Yes |
Examples | HashMap,Vector,ArrayList,HashSet | CopyOnWriteArrayList, ConcurrentHashMap |
public class SimpleFailFastExample {
public static void main(String[] args) {
Map dayIndex = new HashMap();
dayIndex.put("1", "Sunday");
dayIndex.put("2", "Monday");
dayIndex.put("3","Tuesday");
Iterator iterator = dayIndex.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(dayIndex.get(iterator.next()));
dayIndex.put("4", "Wednesday");
}
}
}
Output:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
public class SimpleFailSafeExample {
public static void main(String[] args) {
ConcurrentMap dayIndex = new ConcurrentHashMap();
dayIndex.put("1", "Sunday");
dayIndex.put("2", "Monday");
dayIndex.put("3","Tuesday");
Iterator iterator = dayIndex.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(dayIndex.get(iterator.next()));
dayIndex.put("4", "Wednesday");
}
}
}
Output:
Sunday
Monday
Tuesday
Recommend Reading