Fail Fast and Fail Safe Iterator in Java
Iterators in Java are part of the Java Collection framework. They are used to retrieve elements one by one. The Java Collection supports two types of iterators; Fail Fast and Fail Safe. These iterators are very useful in exception handling.
The Fail fast iterator aborts the operation as soon it exposes failures and stops the entire operation. Comparatively, Fail Safe iterator doesn't abort the operation in case of a failure. Instead, it tries to avoid failures as much as possible.
In this section, we will discuss both the fail fast and Fail Safe iterators with examples. Further, we will see the differences between them.
Before understanding the Fail fast and Fail Safe iterator, let's understand the concurrent modification:
The Concurrent modification in Java is to modify an object concurrently while another task is running over it. In simple terms, concurrent modification is the process of modifying objects while another thread is running over them. It will change the structure of the data collection, either by removing, adding, or updating the value of the elements in the collection.
Not all iterators support this behavior; implementation of some iterator may throw ConcurrentModificationException.
Let's understand the Fail Fast and Fail Safe systems:
Fail Fast and Fail Safe Systems
The Fail Fast system is a system that shuts down immediately after an error is reported. All the operations will be aborted instantly in it.
The Fail Safe is a system that continues to operate even after an error or fail has occurred. These systems do not abort the operations instantly; instead, they will try to hide the errors and will try to avoid failures as much as possible.
Fail Fast Iterator
The iterator in Java is used to traverse over a collection's objects. The collections return two types of iterators, either it will be Fail Fast or Fail Safe.
The Fail Fast iterators immediately throw ConcurrentModificationException in case of structural modification of the collection. Structural modification means adding, removing, updating the value of an element in a data collection while another thread is iterating over that collection. Some examples of Fail Fast iterator are iterator on ArrayList, HashMap collection classes.
How it Works
The Fail Fast iterator uses an internal flag called modCount to know the status of the collection, whether the collection is structurally modified or not. The modCount flag is updated each time a collection is modified; it checks the next value; if it finds, then the modCount will be modified after this iterator has been created. It will throw ConcurrentModificationException.
Consider the below example to understand the behaviour of the Fail Fast iterator:
LA Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445) at java.util.HashMap$KeyIterator.next(HashMap.java:1469) at FailFastDemo.main(FailFastDemo.java:14)
From the above output, we can notice the following points:
Fail Safe Iterator
The Fail Safe iterators are just opposite to Fail Fast iterators; unlike them, A fail-safe iterator does not throw any exceptions unless it can handle if the collection is modified during the iteration process. This can be done because they operate on the copy of the collection object instead of the original object. The structural changes performed on the original collection ignored by them and affect the copied collection, not the original collection. So, the original collection will be kept structurally unchanged.
However, there is not any actual word written as Fail Safe in Java SE documentation; instead, the Fail Safe is termed as a non-Fail fast iterator.
Let's understand its behaviour with some examples:
1 7 9 11
From the above example, we can see the collection is iterating while the other thread is printing the result. The output is not affected by the other operation; this means a separated copy of the collection is created, and the iteration is performed over that.
However, it is not necessary that a collection that does not use the Fail Fast iterator create a clone or copy of it in memory to avoid the ConcurrentModificationException. For example, the ConcurrentHashMap does not operate on a separate copy of an object, although it does not fail fast. Instead, it uses semantics that is specified by the specification as non-fail fast iteration.
Consider the below example:
EIGHT : 8 FIVE : 5 NINE : 9 ONE : 1 SEVEN : 7
From the above example, we can see we are iterating the collection while the other thread is performing. The iteration result is placed in the same collection, which means it is not creating any separate copy of the object and also does not throwing any ConcurrentModificationException.
From the above examples, we can notice the following points about the Fail Safe iterators:
Difference Between Fail Fast and Fail Safe Iterators
The Major difference between Fail Fast and Fail Safe iterator is that the Fail Safe does not throw any ConcurrentModificationException in modifying the object during the iteration process, contrary to fail fast, which throws an exception in such scenarios. This is because the Fail Safe iterator works on a cloned collection instead of the original collection.
There are several other comparisons between them on the basis of different parameters. Let's discuss them: