Iterators in Java typically expect exclusive access to the data structure they loop through. If another thread tries to modify a collection of objects while an iterator processes them, a ConcurrentModificationException gets thrown. Due to the complexity associated with managing arbitrarily scheduled threads, troubleshooting the ConcurrentModificationException can be difficult. Fortunately, Java provides a simple mechanism to help developers avoid this exception.
Java iterators are divided into two separate camps: fail-fast and fail-safe. It is the fail-fast iterator that throws the ConcurrentModificationException. As the name implies, fail-safe iterators will not throw this exception. Of course, the decision to use a fail-safe iterator requires more consideration than simply the desire to avoid runtime exceptions.
Benefits of fail-safe iterators
Fail-safe iterators don't throw exceptions when structural changes happen to the collection of interest, because they work with a clone, not the collection itself. As a result, changes that happen to the underlying collection are ignored by a fail-safe iterator.
The key benefit provided by a fail-safe iterator is the fact that they minimize the possibility of exceptions being thrown. But that benefit comes with a cost, one of which is increased memory requirement. Any time the JVM clones an object, additional memory space is required. With a large collection, the memory footprint can be significant.
Drawbacks of the fail-safe iterator
If the JVM allocates and deallocates increasing amounts of memory, garbage collection routines will have to run more frequently. This will increase the CPU load, trigger a stop-the-world event and reduce overall application performance.
The other drawback is the fact that the results it provides may be out of sync with the underlying collection. After all, the clone will not reflect any changes that happen to the underlying collection after the clone was made. If such an inconsistency is not acceptable to your application, you should not use fail-safe iterators.
The ArrayList and HashMap classes, have fail-fast iterators. The CopyOnWriteArrayList and ConcurrentHashMap classes use fail-safe iterators.
Fail-safe vs. fail-fast Java iterators
If the goal is to avoid exceptions, system resources are in plentiful supply, and updates to the underlying collection class while the iterator runs will not negatively impact your application's business requirements, a fail-safe iterator is a smart choice. Otherwise, stick with iterators that fail fast.
About the author
Dmytro Vezhnin is CEO and co-founder at CodeGym.cc, an interactive educational platform where people can learn Java programming language from scratch to Java Junior level.