关于list的ConcurrentModificationException 异常

原创 2016年05月31日 12:10:59

ConcurrentModificationException–java.lang.RuntimeException,一个运行时错误。
此类在源码中的注解为:
/**
* An {@code ConcurrentModificationException} is thrown when a Collection is
* modified and an existing iterator on the Collection is used to modify the
* Collection as well.
*/
意思大致为:在一个集合被修改以及一个现有的集合的迭代器被用于修改此集合时会抛出一个此异常。

下面从List开始分析,List是Java中的一个Interface(接口),List中定义了add()、get()、contain()、remove()、iterator()等方法(iterator()方法返回的为一个Iterator对象)。List接口被AbstractList实现,此类为一抽象类(从1.2版本开始出现,ArrayList并不是直接实现List接口),ArrayList继承AbstractList具体重写了add()等方法,同时ArrayList中有一内部类ArrayListIterator,此类具有hasNext()与next()方法。

使用Iterator与foreach循环list原理都是使用的ArrayListIterator,执行ArrayListIterator的hasNext()与next()方法。

@Override public Iterator<E> iterator() {
        return new ArrayListIterator();
    }

ArrayListIterator中的hasNext()与next()方法为:

public boolean hasNext() {
            return remaining != 0;
        }

@SuppressWarnings("unchecked") public E next() {
            ArrayList<E> ourList = ArrayList.this;
            int rem = remaining;
            if (ourList.modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            if (rem == 0) {
                throw new NoSuchElementException();
            }
            remaining = rem - 1;
            return (E) ourList.array[removalIndex = ourList.size - rem];
        }

hasNext()方法中的remaining值初始为list大小,随着每循环一次,该值会在next()方法中减1,直至为0,hasNext()方法返回false,也就不再执行next()方法。
next()方法中会判断ourList.modCount的值与expectedModCount值是否相等,其实异常的根源就出自于此,expectedModCount是ArrayListIterator的一个属性,初始化被赋予modCount的值。
这里写图片描述
而modCount为AbstractList属性,值为list的大小,此变量在remove()方法中执行的++操作,因此如果在foreach或者使用Iterator循环中对除最后一个元素之外的其他元素执行remove()操作,modCount的值会被改变,从而在next()方法中的

if (ourList.modCount != expectedModCount) {
     throw new ConcurrentModificationException();
}

判断会抛出ConcurrentModificationException。

此异常也有特例,上边说了对除最后一个元素之外的元素执行remove操作才会报异常,那么如果是对最后一个元素执行删除操作呢?答案是不会抛出异常的,虽然modCount变量值在remove()方法中改变了,但在循环到最后一个元素时remaining的值已经变为了0,所以hasNext()方法返回true,不在执行next()方法,因此不在抛出异常。

关于此异常还是有解决办法的,Java中提供有CopyOnWriteArrayList,可以使用此类代替ArrayList,关于CopyOnWriteArrayList会在之后进行分析。

版权声明:本文为博主原创文章,未经博主允许不得转载。

循环List删除元素抛ConcurrentModificationException异常原因分析

使用for(Object obj:list)进行循环ArrayList时,如果循环删除list中的元素则会抛出 ConcurrentModificationException异常,如下图: ...
  • m0_37372711
  • m0_37372711
  • 2017年01月19日 11:05
  • 303

java.util.ConcurrentModificationException 解决 Android

java.util.ConcurrentModificationException 解决 Android java 在项目里面 遇到了这个bug : E/AndroidRuntim...
  • aaawqqq
  • aaawqqq
  • 2015年02月20日 00:08
  • 14398

ConcurrentModificationException异常解决办法

1、 在开发自己的第一款app,在操作存放子弹的ArrayList时,报出java.util.ConcurrentModificationException异常,因为该异常是非捕获型异常而且很少见,...
  • jason0539
  • jason0539
  • 2013年05月30日 23:56
  • 5404

ConcurrentModificationException异常总结-多线程方式

java.util.ConcurrentModificationException异常总结-多线程方式
  • yuechang5
  • yuechang5
  • 2015年07月12日 11:00
  • 961

Java ConcurrentModificationException异常原因和解决方法

转自: http://www.cnblogs.com/dolphin0520/p/3933551.html  参考资料:   http://blog.csdn.net/izard99...
  • androidboy365
  • androidboy365
  • 2016年01月19日 08:07
  • 15113

Java并发修改错误ConcurrentModificationException分析

1. 介绍 并发修改ConcurrentModificationException错误是开发中一个常见错误,多发生在对一个Collection边遍历边做影响size变化的操作中,下面以ArrayL...
  • wchicho
  • wchicho
  • 2016年07月22日 10:17
  • 4462

Java 遍历List ConcurrentModificationException 异常解析

ConcurrentModificationException 异常解析
  • qq_30051139
  • qq_30051139
  • 2017年01月04日 14:56
  • 691

关于List的ConcurrentModificationException

对ArrayList的操作我们可以通过索引象来访问,也可以通过Iterator来访问,只要不对ArrayList结构上进行修改都不会造成ConcurrentModificationException,...
  • wwbmyos
  • wwbmyos
  • 2012年08月20日 16:19
  • 22301

List remove时出错"ConcurrentModificationException"

1. 现象: 在遍历list的时候,出现错误
  • liranke
  • liranke
  • 2014年04月28日 18:15
  • 2735

使用lambda进行forEach时报ConcurrentModificationException异常

异常:java.util.ConcurrentModificationException:原因猜测:list进行sublist操作会对内部进行引用,同时返回类型不保证是ArrayList类型,因此进行...
  • Dior_wjy
  • Dior_wjy
  • 2017年12月18日 22:22
  • 32
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于list的ConcurrentModificationException 异常
举报原因:
原因补充:

(最多只允许输入30个字)