java.util.ConcurrentModificationException异常分析

java.util.ConcurrentModificationException异常分析

java.util.ConcurrentModificationException

原因:迭代器遍历过程中,调用了集合的remove操作。

复现:

List<Integer> list = new LinkedList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        Iterator<Integer> iterator = list.iterator();
        for (Integer n: list) {
            list.remove(n);
        }

抛出异常:

java.util.ConcurrentModificationException

异常原因:LinkedList 的remove方法只会修改modCount的值而不修改expectedModCount的值

Iterator<Integer> iterator = list.iterator();

这条语句,其实是创建了一个ListItr的对象,ListItr是LinkedList的一个内部类,定义如下:

private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;
        //注:内部类方法可以访问该类定义所在的作用域中的数据

其中,modCount是LinkedList继承自祖先类AbstractList的属性,表示LinkedList被结构修改的次数,结构修改可以简单地理解为改变链表大小的操作,expectedModCount 为期望值。
当执行LinkedList的remove操作时,LinkedList的remove方法只会修改modCount的值,而不会修改expectedModCount 的值,在遍历下一个元素时,调用next()方法,会对modCountexpectedModCount进行比较,如果不相等,抛出并发修改异常,即java.util.ConcurrentModificationException。

		public E next() {
            checkForComodification();
		}
		final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

迭代器的remove等方法

迭代器的remove方法会修改modCountexpectedModCount,以下代码正常运行

 List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            iterator.next();
            iterator.remove();
        }

对 next 方法和 remove 方法的调用具有互相依赖性。如果调用 remove 之前没有调用 next 将是不合法的。如果这样做, 将会抛出一个 IllegalStateException 异常。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值