标签:ons add new stl set bugs arrays ash tee color
Reference
[1] http://netjs.blogspot.co.uk/2015/05/fail-fast-vs-fail-safe-iterator-in-java.html
The collections which are there from Java 1.2 (or even legacy) like ArrayList, Vector, HashSet, HashMap all have fail-fast iterator whereas Concurrent collections added in Java 1.5 like ConcurrrentHashMap, CopyOnWriteArrayList, CopyOnWriteArraySet have fail-safe iterator.
The key differences between the fail-fast and fail-safe iterator
An iterator is considered fail-fast if it throws a ConcurrentModificationException under either of the following two conditions:
fail-fast iterator fails if the underlying collection is structurally modified at any time after the iterator is created, thus the iterator will throw a ConcurrentModificationException if the underlying collection is structurally modified in any way except through the iterator‘s own remove or add (if applicable as in list-iterator) methods.
Note that structural modification is any operation that adds or deletes one or more elements; merely setting the value of an element (in case of list) or changing the value associated with an existing key (in case of map) is not a structural modification.
Mostly Iterators from java.util package throw ConcurrentModificationException if collection was modified by collection‘s methods (add / remove) while iterating
Also note that according to Oracle Docs 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.
1) The following codes will throw ConcurrentModificationException
public class FailFastModification { public static void main(String[] args) { // creating map Map <String,String> cityMap = new HashMap<String,String>(); cityMap.put("1","New York City" ); cityMap.put("2", "New Delhi"); cityMap.put("3", "Newark"); cityMap.put("4", "Newport"); // getting iterator Iterator <String> itr = cityMap.keySet().iterator(); while (itr.hasNext()){ System.out.println(cityMap.get(itr.next())); // trying to add new value to a map while iterating it, will throw ConcurrentModificationException cityMap.put("5", "New City"); } } }
2) The following method to just update values is allowed and will not throw ConcurrentModificationException
public class FailFastModification { public static void main(String[] args) { // creating map Map <String,String> cityMap = new HashMap<String,String>(); cityMap.put("1","New York City" ); cityMap.put("2", "New Delhi"); cityMap.put("3", "Newark"); cityMap.put("4", "Newport"); // getting iterator Iterator <String> itr = cityMap.keySet().iterator(); while (itr.hasNext()){ System.out.println(cityMap.get(itr.next())); // updating existing value while iterating cityMap.put("3", "New City"); } } }
2) The following method to remove values using iterator itself is allowed and will not throw ConcurrentModificationException
public class FailFastModification { public static void main(String[] args) { Map <String,String> cityMap = new HashMap<String,String>(); cityMap.put("1","New York City" ); cityMap.put("2", "New Delhi"); cityMap.put("3", "Newark"); cityMap.put("4", "Newport"); System.out.println("size before iteration " + cityMap.size()); Iterator <String> itr = cityMap.keySet().iterator(); while (itr.hasNext()){ System.out.println(cityMap.get(itr.next())); // removing value using iterator remove method itr.remove(); } System.out.println("size after iteration " + cityMap.size()); } }
In case of fail-safe iterator, ConcurrentModificationException is not thrown as the fail-safe iterator makes a copy of the underlying structure and iteration is done over that snapshot.
Since iteration is done over a copy of the collection so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.
Drawback of using a copy of the collection rather than original collection is that the iterator will not reflect additions, removals, or changes to the collection since the iterator was created. Element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.
Iterator of CopyOnWriteArrayList is an example of fail-safe Iterator also iterator provided by ConcurrentHashMap keySet is fail-safe and never throws ConcurrentModificationException.
Look at the following example of a fail-safe iterator
public class FailSafeTest { public static void main(String[] args) { List <String> cityList = new CopyOnWriteArrayList<String>(); cityList.add("New York City"); cityList.add("New Delhi"); cityList.add("Newark"); cityList.add("Newport"); Iterator<String> itr = cityList.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); cityList.add("NewCity"); //itr.remove(); } } }
This program won‘t throw ConcurrentModificationException as iterator used with CopyOnWriteArrayList is fail-safe iterator.
If we uncomment the line //itr.remove(); this program will throw UnsupportedOperationException as fail-safe iterator does not support remove, set, and add operations.
fail-fast vs fail-safe iterator in Java
标签:ons add new stl set bugs arrays ash tee color
原文地址:http://www.cnblogs.com/codingforum/p/6947532.html