fail-fast vs fail-safe iterator in Java

來源:互聯網
上載者:User

標籤: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

    1. fail-fast iterator throws ConcurrentModificationException if the underlying collection is structurally modified in any way except through the iterator‘s own remove or add methods.
      fail-safe iterator doesn‘t throw ConcurrentModificationException.
    2. fail-fast iterator work on the original collection.
      fail-safe iterator makes a copy of the underlying structure and iteration is done over that snapshot. 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.
    3. fail-fast iterator provides remove, set, and add operations. Note that not all the iterators support all these methods. As exp.ListIterator supports add() method but the general iterator doesn‘t.
      With fail-safe iterator element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.
fail-fast iterator in Java

An iterator is considered fail-fast if it throws a ConcurrentModificationException under either of the following two conditions:

  • In multi-threaded environment, if one thread is trying to modify a Collection while another thread is iterating over it.
  • Even with single thread, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

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());            }}
Fail Safe iterator

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.

Summary
  • An iterator is considered fail-fast if it throws a ConcurrentModificationException in case the underlying collection‘s structure is modified.
  • While iterating a list or a map values can be updated, only if an attempt is made to add or remove from the collection ConcurrentModificationException will be thrown by fail-fast iterator.
  • Fail-fast iterators throw ConcurrentModificationException on a best-effort basis and fail-fast behavior of an iterator cannot be guaranteed.
  • fail-safe iterator works with a copy of the collection rather than the original collection thus interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.
  • remove, set, and add operations are not supported with fail-safe iterator.

fail-fast vs fail-safe iterator in Java

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.