并发修改异常ConcurrentModificationException

  • Post author:
  • Post category:其他




并发修改异常ConcurrentModificationException


产生原因


迭代器遍历过程中,通过集合对象add()方法修改了集合中的元素,使成员变量

modCount++

(此为实际修改次数)。造成了迭代器获取元素中,判断预期修改次数与实际修改次数不一致—-

modCount!=expectedModCount

而抛出了并发修改异常。

public class List {
        public static void main(String[] args) {
            //创建集合对象
            java.util.List<String> list=new ArrayList<String>();
            
            //添加元素
            list.add("hello");
            list.add("world");
            list.add("java");
            
            //遍历集合,得到每一元素,看有没有“world”这个元素
            Iterator<String> it=list.iterator();
            while(it.hasNext()){
                String s=it.next();
                if(s.equals("world")){
                    list.add("javaee");
                }
            }
            //输出集合对象
            System.out.println(list);
            
        }
    }


列如




第一步



先在上面代码中如果String s通过equals()方法判断和”world”内容相对,将调用list集合

方法add

(),成员变量modCount++实际修改的值加一。


add()方法:

public boolean add(E e) {
        modCount++;//实际修改的值自增
        add(e, elementData, size);
        return true;
    }


第二步:


while进行循环判断,it.hasNext()返回为true,执行String s=it.next()语句;将调用迭代器的

next()方法

,通过checkForComodification()判断modCount != expectedModCount抛出并发修改异常;


最开始时迭代器的实现类执行

i

nt expectedModCount = modCount;实际修改次数与预期修改次数相等,但在迭代遍历过程中调用了

add()

方法使的modCounter的值改变




next()方法:

 private class Itr implements Iterator<E> {
    int expectedModCount = modCount;
    /*
    modCount:实际修改的次数
    expectedModCount:预期修改的次数
    */
    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];
           }

    final void checkForComodification() {
                if (modCount != expectedModCount)//判断实际修改次数与预期修改次数是否不等,若不等则抛出并发修改异常
                    throw new ConcurrentModificationException();
            }
   }

解决办法:.不使用迭代器遍历,使用普通for遍历。



版权声明:本文为weixin_45733740原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。