user1703879
user1703879

Reputation: 43

Why iterators are called fail safe or fail fast?

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 ?

Upvotes: 0

Views: 1773

Answers (4)

Dzmtrs
Dzmtrs

Reputation: 446

My answer includes two points.

  1. To the answer marked correct, it is important to add that fail-fast behaviour of iterators is not 100% reliable (and API docs state that). The docs say it behaves on the best-effort basis and it is advised to use it only for bugs detection:

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs

Thus, you probably should take this behaviour into account when writing code, but you definitely must not fully rely on it.

  1. There is a very good article on that. I know it was written later than asked. However, I find it useful to understand what's called concurrent modification policy.

So, there are four policies, and among them there is no fail-safe one:

  1. Fail-fast
  2. Weakly consistent
  3. Snapshot
  4. undefined

The conclusion from the article says:

After all this, where does “fail-safe” come into the picture? Answer: it doesn’t. The words “fail-safe” are never used in the Java SE specifications that describe the concurrent modification policy of a collection. As such, there is no reliable, consistent definition of “fail-safe” for an Iterator. One can attempt to apply the general concept of “fail-safety” to an Iterator, but this is open to varying, misleading, and even contradictory interpretations.

Don’t use “fail-safe” to describe a Java Iterator. Instead, use one of the documented policies listed above.

Upvotes: 1

Siddharth Sonwane
Siddharth Sonwane

Reputation: 51

  • Fail-safe iterators means they will not throw any exception even if the collection is modified while iterating over it.
  • Whereas Fail-fast iterators throw an exception(ConcurrentModificationException) if the collection is modified while iterating over it.

Upvotes: 0

V33R
V33R

Reputation: 989

As name suggest fail-fast Iterators fail as soon as they realized that structure of Collection has been changed since iteration has begun. Structural changes means adding, removing or updating any element from collection while one thread is Iterating over that collection. fail-fast behavior is implemented by keeping a modification count and if iteration thread realizes the change in modification count it throws ConcurrentModificationException.

Contrary to fail-fast Iterator, fail-safe iterator doesn't throw any Exception if Collection is modified structurally while one thread is Iterating over it 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.

Upvotes: 3

Stewart
Stewart

Reputation: 18304

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.

Upvotes: 4

Related Questions