Why are iterators called "fail-safe" and "fail-fast" even though Iterator.remove()
doesn't throw any ConcurrentModificationException
while iterating through a Collection
(for example, HashMap
) using Iterator
?
Using Iterator.remove()
doesn't throw ConcurrentModificationException
, but if something else (in another thread) modifies the Collection
which backs the Iterator
during iteration, then it will.
From the Java API docs for java.util.ArrayList
; bold emphasis added by me:
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException
.
The next sentence of the same documentation then explains exactly what is meant by fail-fast in this case; again, bold emphasis added by me:
Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
In other words, the simple and safe thing to do, if another thread modifies the collection, is to cause a deliberate, explicit failure in the form of ConcurrentModificationException
, rather than attempting to work out a non-failing, ie fail-safe, logic (such as having the modification show up via the Iterator
depending upon whether that element has already been iterated over) which could be complex and error-prone.