Original address: http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fail-safe-iterator-difference-with-example-in-Java.html
Before we discuss the differences between the two mechanisms in detail, we first need to understand the concurrency changes.
1. What is sync modification?
When one or more threads are traversing a collection collection, another thread modifies the contents of the collection (add, delete, or modify). This is the concurrent modification
2. What is the fail-fast mechanism?
The fail-fast mechanism, when traversing a set, throws concurrent modification Exception when the collection structure is modified.
Fail-fast will be thrown in the following two cases concurrentmodificationexception
(1) Single thread environment
After the collection has been created, the structure is modified during the traversal of it.
Note that the Remove () method causes Expectmodcount and modcount to be equal, so this exception is not thrown.
(2) Multi-threaded environment
When a thread is traversing this collection, another thread modifies the structure of the collection.
Note that the fast failure behavior of iterators is not guaranteed because, in general, it is not possible to make any hard guarantees as to whether or not there is a concurrency change in sync. A fast-failing iterator will do its best to throw concurrentmodificationexception. Therefore, it is a mistake to write a program that relies on this exception to improve the correctness of such iterators: The fast failure behavior of iterators should only be used to detect bugs.
3. How is the fail-fast mechanism detected?
Iterators have direct access to internal data during traversal, so the internal data cannot be modified during traversal. To ensure that it is not modified, the iterator internally maintains a tag "mode", when the set structure changes (add delete or modify), the tag "mode" is modified, and the iterator each time the Hasnext () and Next () method will check whether the "mode" is changed, when the detection is modified, Throw Concurrent Modification Exception
Here's a look at the source code for the ArrayList iterator section
[Java]View PlainCopy
Private class Itr implements Iterator<E> {
Int cursor;
Int lastRet = -1;
Int expectedModCount = ArrayList.this.modCount;
Public boolean hasNext() {
Return (this.cursor != ArrayList.this.size);
}
Public E next() {
checkForComodification();
/** Omit the code here */
}
Public void remove() {
If (this.lastRet < 0)
Throw new IllegalStateException();
checkForComodification();
/** Omit the code here */
}
Final void checkForComodification() {
If (ArrayList.this.modCount == this.expectedModCount)
Return;
Throw new ConcurrentModificationException();
}
}
Can see it's labeled "Mode" for Expectedmodecount
4. Fail-Safe mechanism
Fail-Safe any modifications to the collection structure will be modified on a replicated set, so no concurrentmodificationexception will be thrown
There are two problems with the fail-safe mechanism
(1) The need to replicate the collection, resulting in a large number of invalid objects, overhead
(2) data that is not guaranteed to be read is the data in the current raw data structure.
5 examples of fail-fast and fail-safe
[Java]View PlainCopy
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
-
- public class FailFastExample
- {
-
-
- public static void main(String[] args)
- {
- Map<String,String> premiumPhone = new HashMap<String,String>();
- premiumPhone.put("Apple", "iPhone");
- premiumPhone.put("HTC", "HTC one");
- premiumPhone.put("Samsung","S5");
-
- Iterator iterator = premiumPhone.keySet().iterator();
-
- while (iterator.hasNext())
- {
- System.out.println(premiumPhone.get(iterator.next()));
- premiumPhone.put("Sony", "Xperia Z");
- }
-
- }
-
- }
Output
iPhone
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at FailFastExample.main(FailFastExample.java:20)
[Java]View PlainCopy
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.Iterator;
-
-
- public class FailSafeExample
- {
-
-
- public static void main(String[] args)
- {
- ConcurrentHashMap<String,String> premiumPhone =
- new ConcurrentHashMap<String,String>();
- premiumPhone.put("Apple", "iPhone");
- premiumPhone.put("HTC", "HTC one");
- premiumPhone.put("Samsung","S5");
-
- Iterator iterator = premiumPhone.keySet().iterator();
-
- while (iterator.hasNext())
- {
- System.out.println(premiumPhone.get(iterator.next()));
- premiumPhone.put("Sony", "Xperia Z");
- }
-
- }
-
- }
Output
S5
HTC one
iPhone
6. The difference between fail-fast and fail-safe
|
fail Fast Iterator |
Fail Safe Iterator |
Throw concurrentmodification Exception |
Yes |
No |
Clone Object |
No |
Yes |
Memory Overhead |
No |
Yes |
Examples |
Hashmap,vector,arraylist,hashset |
Copyonwritearraylist, Concurrenthashmap |
The difference between fail-fast and fail-safe in Java