首页 > 其他 > 详细

fail-fast和modcount

时间:2016-02-09 11:13:29      阅读:272      评论:0      收藏:0      [点我收藏+]

Arraylist,HashMap,HashSet等容器持有的的fail-fast迭代器,具体实现原理和modcount域有关.

 Lets looks at following code 

01 public class FailFastIteratorTest {
02 
03   public static void main(String[] args) {
04     
05     final List<String> list = new ArrayList<String>();
06     list.add("a");
07     list.add("b");
08     list.add("c");
09     
10     Iterator<String> it = list.iterator();
11     
12     Thread t = new Thread() {
13 
14       public void run() {
15         list.add("d");
16         list.add("e");
17         list.add("f");
18       }
19     };
20     t.start();
21     
22     // Make sure, thread gets kicked off
23     try {
24       Thread.sleep(1000);
25     } catch (InterruptedException e) {
26     }
27     
28     while(it.hasNext()){
29       System.out.println(it.next());
30     }
31   }
32 }

What will happen when above program is run ? Hope you have guessed it right, you will get java.util.ConcurrentModificationException thrown at line it.next(). Because its not allowed for a thread to modify the collection, while another is iterating over it. Ok, lets make it single threaded and modify code (lines 06 to 30) as below: 

1 list.add("a");
2 list.add("b");
3 list.add("c");
4 
5 Iterator<String> it = list.iterator();
6 list.add("d");
7 while(it.hasNext()){
8   System.out.println(it.next());
9 }

Huh!.. again you will get throw ConcurrentModificationException thrown at line it.next(). After the creation of Iterator, the container cannot be modified at any time by any method other than the Iterator‘s own remove or add methods. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future. Ok Now lets dig little deep and ascertain how fail-fast iterators are implemented. Java uses modCount variable to track number of modifications made. Here goes the javadoc comments for declaraion of modCount variable in AbstractList class. 

01 /**
02 * The number of times this list has been structurally modified.
03 * Structural modifications are those that change the size of the
04 * list, or otherwise perturb it in such a fashion that iterations in
05 * progress may yield incorrect results.
06 *
07 * This field is used by the iterator and list iterator implementation
08 * returned by the iterator and listIterator methods.
09 * If the value of this field changes unexpectedly, the iterator (or list
10 * iterator) will throw a ConcurrentModificationException in
11 * response to the next, remove, previous, set or add operations.  
12 * This provides fail-fast behavior, rather than non-deterministic behavior in
13 * the face of concurrent modification during iteration.
14 *
15 * Use of this field by subclasses is optional. If a subclass
16 * wishes to provide fail-fast iterators (and list iterators), then it
17 * merely has to increment this field in its add(int, Object) and
18 * remove(int) methods (and any other methods that it overrides
19 * that result in structural modifications to the list).  A single call to
20 * add(int, Object) or remove(int) must add no more than
21 * one to this field, or the iterators (and list iterators) will throw
22 * bogus ConcurrentModificationExceptions.  If an implementation
23 * does not wish to provide fail-fast iterators, this field may be
24 * ignored.
25 */
26 protected transient int modCount = 0;
27 
28 Now lets look at implementation iterator class returned by list.
29 
30 private class Itr implements Iterator<E> {
31   int expectedModCount = modCount;
32 
33   public boolean hasNext() {
34       // implementation omitted            
35   }
36 
37   public E next() {
38             checkForComodification();
39             // implementation omitted     
40       
41   }
42 
43   private void checkForComodification() {
44       if (modCount != expectedModCount)
45     throw new ConcurrentModificationException();
46   }
47  }

As it is clear, expectedModCount is initialized to modCount at creation of Iterator and any method that modify the list would increament modCount. Every call to next() method, checks expectedModCount and throws ConcurrentModificationException if it does not match with modCount. 

fail-fast和modcount

原文:http://www.cnblogs.com/Guoyutian/p/5185456.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!