集合中出现ConcurrentModificationException异常

项目中用了集合的subList方法,然后又size一下。后来跑起来的时候报异常:ConcurrentModificationException。第一次遇见这个异常,仅从字面意思上以为和多线程并发有关系,但是仔细想想,发生异常的代码并不会出现多线程并发问题。经过查找资料,并且看了相关源码才明白其中原理。

集合中出现ConcurrentModificationException异常被称为集合的fail-fast机制。这样机制主要用来检测集合修改前是否已经被修改,确保在多线程中数据保证一致性。很多人说是因为多线程并发导致该异常,其实不完全是,我这里出现异常就是在单线程中发生。

出现ConcurrentModificationException异常主要是因为调用集合内部调用checkForComodification方法。方法内容

    private void checkForComodification() {
        if (l.modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
当出现modCount!=expectedModCount时候就会异常。

1.当有多个线程操作一个集合时,一个线程iterable便利,另一个线程增加或者删除,只要改变原来集合数量。这样情况下回发生ConcurrentModificationException。因为集合iterator方法后会返回一个内部类Itr(),该方法的next,remove,previous方法中都有checkForComodification()方法。内容同上代码。Itr内部类的expectedModCount是直接来自AbstractList字段modCount,modCount字段就是原集合中字段。所以,一旦原集合变化但是生产Itr(即迭代器)modCount没有一起发生变化才导致这样问题。

2.当有且只有一个线程情况下,不存在多并发下操作线程时,使用subList方法后然后,对原list集合操作(新增一个,删除一个或者清除全部),最后在调用子集合中size,或者别的有checkForComodification方法的方法时也会发生异常.subList在AbstractList中实现是如下代码

    public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<E>(this, fromIndex, toIndex) :
                new SubList<E>(this, fromIndex, toIndex));
    }

在SubList构造函数中代码如下

    SubList(AbstractList<E> list, int fromIndex, int toIndex) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if (toIndex > list.size())
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");
        l = list;
        offset = fromIndex;
        size = toIndex - fromIndex;
        expectedModCount = l.modCount;
    }
构造函数中l.modCount就是this参数的modCount,即原函数的modCount.所以一旦subList调用以后,然后再处理原集合内容,改变modCount,则很容易发生ConcurrentModificationException异常,并且该异常不是并发导致。

参考文献:http://www.cnblogs.com/skywang12345/p/3308762.html#a3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值