There are two types of iterators in Java: fail-safe and fail-fast.
What does this mean, and is the difference between them?
There are two types of iterators in Java: fail-safe and fail-fast.
What does this mean, and is the difference between them?
The only difference is fail-safe iterator doesn't throw any Exception, contrary to fail-fast Iterator.
If Collection is modified structurally while one thread is iterating over it. This is because they work on clone of Collection instead of original collection and that’s why they are called as fail-safe iterator.
Iterator of CopyOnWriteArrayList is an example of fail-safe Iterator also iterator written by ConcurrentHashMap keySet is also fail-safe iterator and never throw ConcurrentModificationException in Java.
"Fail safe" means: it won't fail. Strictly speaking, there is no such thing in Java as a fail-safe iterator. The correct term is "weakly consistent". The javadoc says:
Typically, weak consistency means that if a collection is modified concurrently with an iteration, the guarantees of what the iteration sees are weaker. (The details will be specified in each conncurrent collection classes javadocs.)
"Fail fast" means: it may fail ... and the failure condition is checked aggressively so that the failure condition is (where possible1) detected before damage can be done. In Java, a fail-fast iterator fails by throwing a
ConcurrentModificationException
.The alternative to "fail-fast" and "weakly consistent" is a semantic where the iteration fails unpredictably; e.g. to sometimes give the wrong answer or throw a totally unexpected exception. (This was the behavior of some standard implementations of the
Enumeration
API in early versions of Java.)No. These are properties of the iterators implemented by standard Collection types; i.e. they are either "fail fast" or "weakly consistent" ... when used correctly with respect to synchronization and the Java memory model1.
The fail-fast iterators are typically implemented using a
volatile
counter on the collection object.Iterator
is created, the current value of the counter is embedded in theIterator
object.Iterator
operation is performed, the method compares the two counter values and throws a CME if they are different.The implementation of fail-safe iterators is typically light-weight. They typically rely on properties of the specific list implementation's data structures. There is no general pattern. (Read the source code for the specific collection classes you are interested in.)
1 - The rider is that fail-fast behavior assumes that the application id correctly with respect to synchronization and the memory model. That means that (for example) if you iterate an
ArrayList
without proper synchronization, the end result could be a corrupted list result. The "fast fail" mechanism will probably detect the concurrent modification (though that isn't guaranteed), but it won't detect the underlying corruption. As an example, javadoc forVector.iterator()
says this:They are rather fail-fast and weakly-consistent types:
Iterators from
java.util
package throwConcurrentModificationException
if collection was modified by collection's methods (add / remove) while iteratingIterators from
java.util.concurrent
package typically iterate over a snapshot and allow concurrent modifications but may not reflect collection updates after the iterator was created.