关于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集合的时候删除单个(多个)元素(解决并发异常)

Exception in thread "main" java.util.ConcurrentModificationException

List的add方法报空指针异常

/**      * 查询好友列表      */     @Override     @ResponseBody     public J...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

DataGridView绑定List<T>,出现IndexOutOfRangeException异常

最近在测试系统的时候DataGridView出现IndexOutOfRangeException异常,对DataGridView绑定的数据源类型是List。由于DataGridView我使用的是第三方...

List的removeAll方法异常?

现在正在实现的一个模块,是用Hibernate做的,一个用户对应多个频道,用的是一对多的关联,配置方件如下: User表: Java code <!DOCTYPE hiberna...

list操作 出UnsupportedOperationException异常

这两天遇见的问题,感觉说的对,纠结半天了 我们在使用collection框架code时,会时常遇到UnsupportedOperationException异常,有些人很不了解为什么抛出这个异常,会...

关于list的 java.util.ConcurrentModificationException异常处理

今天在做一个数据处理的时候遇到一点问题,因为我需要对一个集合的数据分别截取六分之一然后赋值给六个我需要用到的List集合,然后我对每一个拿到的数据各自在增加一个数据。代码如下:List emojida...

dubbo 异常Please check registry access list (whitelist/blacklist)的分析

dubbo 异常Please check registry access list (whitelist/blacklist)的分析与解决工作中遇到了这个异常,当时仅仅是查了解决方法,但问题解决后自己...

JavaScript异常Uncaught SyntaxError- missing ) after argument list;SyntaxError- identifier starts immed

JavaScript异常Uncaught SyntaxError: missing ) after argument list;SyntaxError: identifier starts immed...

再使用java list的时候出现空指针异常

java.lang.NullPointerException     at action.notice.ViewTriNoticesAction.execute(ViewTriNoticesActi...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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