Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are fail-safe & fail-fast Iterators in Java

There are two types of iterators in Java: fail-safe and fail-fast.

What does this mean, and is the difference between them?

like image 476
Prateek Avatar asked Jun 29 '13 06:06

Prateek


People also ask

What is fail-safe?

Fail-safe means that a device will not endanger lives or property when it fails. Fail-secure, also called fail-closed, means that access or data will not fall into the wrong hands in a security failure.

What is a fail-safe in business?

Fail-safe is a term that, in the past, referred to a protocol used with machinery in which if a primary mechanism failed, it would revert to a safe condition. When dealing with technology in the 21st century, it is important to build-in effective redundancies.


4 Answers

What is the difference between them ...

"Fail-safe" (in engineering) means that something fails in a way that causes no or minimal damage. Strictly speaking, there is no such thing in Java as a fail-safe iterator. If an iterator fails (in the normal sense of "fail"), you can expect damage to occur.

I suspect that you actually mean "weakly consistent" iterators. The javadoc says:

"Most concurrent Collection implementations (including most Queues) also differ from the usual java.util conventions in that their Iterators and Spliterators provide weakly consistent rather than fast-fail traversal."

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 concurrent collection classes javadocs.)

"Fail-fast" (in systems design) means that the failure condition is checked aggressively so that the failure condition is (where possible1) detected before too much damage can be done. In Java, a fail-fast iterator fails by throwing a ConcurrentModificationException.

The alternative to "fail-fast" and "weakly consistent" is semantic where the iteration fails unpredictably; e.g. to sometimes give the wrong answer or throw an unexpected exception. (This was the behavior of some standard implementations of the Enumeration API in early versions of Java.)

... and are they different from the iterator we use for collection.

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.


Fail-fast iterators are typically implemented using a volatile counter on the collection object.

  • When the collection is updated, the counter is incremented.
  • When an Iterator is created, the current value of the counter is embedded in the Iterator object.
  • When an Iterator operation is performed, the method compares the two counter values and throws a CME if they are different.

By contrast, weakly consistent iterators are typically light-weight and leverage properties of each concurrent collection's internal data structures. There is no general pattern. If you are interested, read the source code for different collection classes.


1 - The rider is that fail-fast iterator behavior assumes that the application is correctly implemented with respect to synchronization and the memory model. (In other words, the application is thread-safe.) For example, if you iterated an ArrayList without proper synchronization, the "fast fail" mechanism should detect the concurrent modification (though that isn't guaranteed), but may not prevent the list from being corrupted due to the application's unsafe behavior. To illustrate, the javadoc for Vector.iterator() says this:

"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."

like image 142
Stephen C Avatar answered Oct 11 '22 19:10

Stephen C


They are rather fail-fast and weakly-consistent types:

Iterators from java.util package throw ConcurrentModificationException if collection was modified by collection's methods (add / remove) while iterating

Iterators 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.

like image 35
Evgeniy Dorofeev Avatar answered Oct 11 '22 21:10

Evgeniy Dorofeev


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.

like image 22
Juned Ahsan Avatar answered Oct 11 '22 20:10

Juned Ahsan


This scenario relate with "concurrent processing", means that more then one user accessing the same resource. In such situation, one of the user try to modify that resource which cause the 'ConcurrentProcessingException' because in that case other user get improper data. Both this type relate with this kind of situation.

In simple term,

Fail-Fast :

  • Iterators immediately throw ConcurrentModificationException if structural modification(add, update, delete) happens.
  • Example : ArrayList, HashMap, TreeSet

Fail-Safe :

  • Here Iterators not throw any exception because they operate on the clone of the collection, not original one. So, that they are fail-safe iterators.
  • Example : CopyOnWriteArrayList, ConcurrentHashMap
like image 2
Dhwanil Patel Avatar answered Oct 11 '22 19:10

Dhwanil Patel