解决java.util.ConcurrentModificationException: null并发修改异常

一.问题:

在我们的日常开发中,可能偶尔也会遇到需要在循环里(新增或修改等操作),如果直接使用for循环遍历就会导致

异常报错:

java.util.ConcurrentModificationException: null

案例:

解决java.util.ConcurrentModificationException: null并发修改异常_第1张图片

在官方文档中ConcurrentModificationException的介绍如下:

public class ConcurrentModificationException extends RuntimeException
当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 
例如,某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常。

ConcurrentModificationException是Java中很常见的一种异常,尤其是使用集合类的时候,很容易出现。

二:原因:

在新增操作以后,集合的expectedModCount和modCount的值不一致这两个变量的作用都是记录修改次数的。二者不相等,所以会抛错。

在ArrayList源码实现中有个判断校验

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

从这段代码可以看出返回的是一个指向Itr类型对象的引用,我们接着看Itr的具体实现,在ArrayList类中找到了Itr类的具体实现,它是ArrayList的一个成员内部类,下面这段代码是Itr类的所有实现:

里面的几个成员变量:

  • cursor:表示下一个要访问的元素的索引,从next()方法的具体实现就可看出
  • lastRet:表示上一个访问的元素的索引
  • expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount。
  • modCount是AbstractList类中的一个成员变量
/**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

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


 

三.解决

可以使用索引遍历(普通for循环)就可以解决,如下

解决java.util.ConcurrentModificationException: null并发修改异常_第2张图片

看完恭喜你,又知道了一点点!!!

你知道的越多,不知道的越多!

~感谢志同道合的你阅读, 你的支持是我学习的最大动力 ! 加油 ,陌生人一起努力,共勉!!

注: 如果本篇有需要改进的地方或错误,欢迎大神们指定一二~~

你可能感兴趣的:(Java,Bug,java,p2p,开发语言)