设为首页 加入收藏

TOP

【Java深入研究】4、fail-fast机制(六)
2017-10-13 10:03:49 】 浏览:5762
Tags:Java 深入 研究 fail-fast 机制
equals(this.elementData[i])))  
  •                 continue;  
  •             fastRemove(i);  
  •             return true;  
  •         }  
  •     return false;  
  • }  
  •   
  • private void fastRemove(int paramInt) {  
  •     this.modCount += 1;   //修改modCount  
  •     /** 省略此处代码 */  
  • }  
  •   
  • public void clear() {  
  •     this.modCount += 1;    //修改modCount  
  •     /** 省略此处代码 */  
  • }  
  •  

            从上面的源代码我们可以看出,ArrayList中无论add、remove、clear方法只要是涉及了改变ArrayList元素的个数的方法都会导致modCount的改变。所以我们这里可以初步判断由于expectedModCount 得值与modCount的改变不同步,导致两者之间不等从而产生fail-fast机制。知道产生fail-fast产生的根本原因了,我们可以有如下场景:

            有两个线程(线程A,线程B),其中线程A负责遍历list、线程B修改list。线程A在遍历list过程的某个时候(此时expectedModCount = modCount=N),线程启动,同时线程B增加一个元素,这是modCount的值发生改变(modCount + 1 = N + 1)。线程A继续遍历执行next方法时,通告checkForComodification方法发现expectedModCount  = N  ,而modCount = N + 1,两者不等,这时就抛出ConcurrentModificationException 异常,从而产生fail-fast机制。

            所以,直到这里我们已经完全了解了fail-fast产生的根本原因了。知道了原因就好找解决办法了。

    三、fail-fast解决办法

            通过前面的实例、源码分析,我想各位已经基本了解了fail-fast的机制,下面我就产生的原因提出解决方案。这里有两种解决方案:

            方案一:在遍历过程中所有涉及到改变modCount值得地方全部加上synchronized或者直接使用Collections.synchronizedList,这样就可以解决。但是不推荐,因为增删造成的同步锁可能会阻塞遍历操作。

            方案二:使用CopyOnWriteArrayList来替换ArrayList。推荐使用该方案。

            CopyOnWriteArrayList为何物?ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。 该类产生的开销比较大,但是在两种情况下,它非常适合使用。1:在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时。2:当遍历操作的数量大大超过可变操作的数量时。遇到这两种情况使用CopyOnWriteArrayList来替代ArrayList再适合不过了。那么为什么CopyOnWriterArrayList可以替代ArrayList呢?

            第一、CopyOnWriterArrayList的无论是从数据结构、定义都和ArrayList一样。它和ArrayList一样,同样是实现List接口,底层使用数组实现。在方法上也包含add、remove、clear、iterator等方法。

            第二、CopyOnWriterArrayList根本就不会产生ConcurrentModificationException异常,也就是它使用迭代器完全不会产生fail-fast机制。请看:

     

    [java]  view plain  copy
     
    1. private static class COWIterator<E> implements ListIterator<E> {  
    2.         /** 省略此处代码 */  
    3.         public E next() {  
    4.             if (!(hasNext()))  
    5.      &
    首页 上一页 3 4 5 6 7 下一页 尾页 6/7/7
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇【Java深入研究】4、fail-fast机制 下一篇【Java基础】4、java中的内部类

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目