Saturday, 19 April 2014

Fail-Safe Vs Fail-Fast iterators in Java

Fail-Fast iterators :

Fail-fast iterators fail as soon as they realize that the structure of the collection has changed since the iteration has begun. By changing the structure of the collection, we mean adding, removing or updating an element in the collection. It is implemented by keeping a modification count and if the iterating thread realizes the change in modification count, it throws ConcurrentModificationException. Most of the collections in Java are fail-fast. This is not a guaranteed behavior. So, we should not rely on this behavior.

We can get ConcurrentModificationException if one thread is iterating over a collection and at the same time that collection is modified by some other thread. Please note that we can get ConcurrentModificationException even in single threaded applications. The following code snippet would throw ConcurrentModificationException :
Whereas, the following code snippet won't throw ConcurrentModificationException :

So, if we use Iterator's remove method, we won't get ConcurrentModificationException. To understand why the second approach doesn't throw ConcurrentModificationException, we need to understand how fail-fast iterators are implemented in Java. The fail-fast iterators are typically implemented using a volatile counter on the list object. When the list is updated, the counter is updated. When an iterator is created, the current value of the counter is embedded in the Iterator object. When an iterator operation is performed, the iterator method compares the list counter with the Iterator counter, and throws ConcurrentModificationException if they differ. That explains why the first code snippet above throws ConcurentModificationException. On the contrary, if we use Iterator's remove method (second code snippet above), the Iterator counter is also decremented. So, in the next iteration, the counter check succeeds. Hence, the second code snippet above doesn't throw ConcurrentModificationException.

Fail-Safe iterators :

Contrary to fail-fast iterators, fail safe iterators don't throw ConcurrentModificationException. This is because they work on clone of collection rather than the original collection. Fail-safe iterators typically operate over a snapshot and allow concurrent modification. But the fail fast iterators may not reflect the updates on collection after the iterator was created. What this implies is that Fail-Fast iterator is guaranteed to list elements as they existed upon iterator construction, and may reflect any modification subsequent to construction of the iterator(without guarantee).  Iterator of CopyOnWriteArrayList and iterators of java.util.concurrent package was fail-fast iterators. Since fail-safe iterators work on cloned objects, they have extra memory overhead.