fail-fast与fail-safe

今天看hashmap源码的时候遇见了fail-fast这个名词,找了一篇博客,学习一下:

What is fail safe and fail fast Iterator in Java? 

Java Collections supports two types of Iterator, fail safe and fail fast. The main distinction between a fail fast and fail safe Iterator is whether or not the underlying collection can be modified while its begin iterated. If you have used Collection like ArrayList then you know that when you iterate over them, no other thread should modify the collection. If Iterator detects any structural change after iteration has begun e.g adding or removing a new element then it throws ConcurrentModificationException,  this is known as fail-fast behavior and these iterator are called  fail-fast iterator because they fail as soon as they detect any modification . Though its not necessary that iterator will throw this exception when multiple threads modified it simultaneously. it can happen even with single thread when you try to remove elements  by using ArrayList's remove() method instead of Iterator's remove method, as discussed in my earlier post,  2 ways to remove objects from ArrayList.

Most of the Collection classes from Java 1.4 e.g. Vector, ArrayList, HashMap, HashSet has fail-fast iterators. The other type of iterator was introduced in Java 1.5 when concurrent collection classes e.g. ConcurrentHashMap, CopyOnWriteArrayList and CopyOnWriteArraySet was introduced. These iterator uses a view of original collection for doing iteration and that's why they doesn't throw ConcurrentModificationException even when original collection was modified after iteration has begun.  This means you could iterate and work with stale value, but this is the cost you need to pay for fail-safe iterator and this feature is clearly documented
理解:java集合支持两种类型的迭代,分别是fail-fast与fail-safe.他们的主要区别是在迭代的时候能否对集合进行修改.如果你用的是ArrayList容器的话,当你进行迭代操作的时候,其他线程是不能够对它进行修改的.如果你在迭代的时候对集合进行添加或者删除操作,就会抛出ConcurrentModificationException异常,这就是所谓的fail-fast机制,因为它能够在觉察到任何修改的时候fail.不光是多线程操作集合的时候会出现这个异常,当你调用迭代调用Arraylist的remove函数而不是Iterator的remove函数的时候也会抛出这个异常.vector,arraylist,hashmap,hashset中用的是fail-fast迭代器,concurrenthashmap,copyonwritelist,copyonwritearrayset用的是fail-safe迭代器.

Difference between Fail Safe and Fail Fast Iterator in Java

In order to best understand difference between these two iterator you need to try out examples with both traditional collections like ArrayList and  concurrent collections like CopyOnWriteArrayList. Nevertheless let's first see some key differences one at a time :

1) Fail-fast Iterator throws ConcurrentModfiicationException as soon as they detect any structural change in collection during iteration, basically which changes the modCount variable hold by Iterator. While fail-fast iterator doesn't throw CME.

2) Fail-fast iterator traverse over original collection class while fail-safe iterator traverse over a copy or view of original collection. That's why they don't detect any change on original collection classes and this also means that you could operate with stale value.

3) Iterators from Java 1.4 Collection classes e.g. ArrayList, HashSet and Vector are fail-fast while Iterators returned by concurrent collection classes e.g.  CopyOnWriteArrayList or  CopyOnWriteArraySet are fail-safe.

4) Iterator returned by synchronized Collection are fail-fast while iterator returned by concurrent collections are fail-safe in Java.

5) Fail fast iterator works in live data but become invalid when data is modified while fail-safe iterator are weekly consistent.
理解:
  1. 当fail-fast迭代器发现容器有任何结构上的改变的时候就会抛出CME,它是根据modcount是否有变化来判断的
  2. fail-fast是在原始的集合上进行遍历操作,而fail-safe迭代器是在原始集合的拷贝上进行遍历
  3. arraylist,hashset,vector是fail-fastt迭代器,copyonwritearraylist和copyonwritearrayset是fail-safe迭代器
  4. synchronized容器返回的fail-fast迭代器,而concurrent容器返回fail-safe迭代器

fail-fast与fail-safe_第1张图片


When to use fail fast and fail safe Iterator

Use fail safe iterator when you are not bothered about Collection to be modified during iteration, as fail-fast iterator will not allow that. Unfortunate you can't choose fail safe or fail fast iterator, it depends upon which Collection class you are using. Most of the JDK 1.4 Collections e.g. HashSet, Vector, ArrayList has fail fast Iterator and only Concurrent Collections introduced in JDK 1.5 e.g. CopyOnWriteArrayList and CopyOnWriteArraySet supports fail safe Iteration. Also if you wan to remove elements during iteration please use iterator's remove() method and don't use remove method provided by Collection classes e.g. ArrayList or HashSet because that will result inConcurrentModificationException.


That's all about  difference between fail-safe and fail-fast iterator in Java. Now you know that its just tow kinds of iterator which behave differently when underlying collection class is modified by adding or removing any object. Keep in mind that when you work with concurrent collection classes like ConcurrentHashMap you work with fail-safe iterator, which will not throw ConcurrentModificationException but not necessarily be holding the most updated view of underlying Collection.

理解:当你需要remove集合中的所有元素的时候,调用iterator的remove函数而不是集合的remove函数,以免引起cme异常

你可能感兴趣的:(fail-fast与fail-safe)