Fail Fast vs Fail Safe Iterator in Java
When multiple threads are concurrently iterating over a collection, if one of the threads alters the structure of the collection during the iteration process, it is referred to as Concurrent Modification. This occurrence triggers the throwing of a ConcurrentModificationException if modifications are made to the collection while it is being iterated. The concepts of fail-fast and fail-safe iterators emerged as relatively recent additions in Java, initially introduced alongside Concurrent Collections such as ConcurrentHashMap and CopyOnWriteArrayList in Java 5.
Java Collections offer support for two distinct types of iterators: Fail-Fast iterators and Fail-Safe iterators. Fail-Fast iterators promptly detect any concurrent modifications and promptly throw a ConcurrentModificationException to maintain a fail-fast behavior. Conversely, Fail-Safe iterators operate on a separate copy of the collection's data and continue the iteration process without throwing any exceptions, even if modifications are made to the collection during the iteration. These concepts are of utmost importance in managing concurrent modifications and provide diverse strategies for handling such scenarios in multi-threaded environments.
Fail-Fast iterators, which are returned by the majority of collection types in Java, do not tolerate any structural modifications to a collection while it is being iterated. In the event that such modifications occur, a fail-fast iterator responds by throwing a ConcurrentModificationException. Structural changes encompass operations such as adding, removing, or updating elements within the collection while another thread is actively iterating over it. Fail-fast behavior is implemented by maintaining a modification count, and if the iterating thread detects a discrepancy in the modification count, it promptly throws the aforementioned exception.
Fail-safe iterators do not throw exceptions if the collection undergoes structural modifications while being iterated by a thread. This is because fail-safe iterators operate on a cloned copy of the collection instead of the original collection, which is why they are referred to as fail-safe iterators. Consequently, any structural modifications made to the actual collection go unnoticed by these iterators. An example of a fail-safe iterator is the iterator of CopyOnWriteArrayList. Additionally, the iterator obtained from the keySet of ConcurrentHashMap is also a fail-safe iterator that does not throw ConcurrentModificationException in Java.
Fail-Fast iterators promptly throw a ConcurrentModificationException if a collection is structurally modified during iteration, prioritizing early detection, while Fail-Safe iterators operate on a cloned copy of the collection, allowing modifications without throwing exceptions, ensuring a stable iteration process.