并发修改异常原理及原因

首先展示一个内容代码

package CCom.Cnn;
//属于util包下,需要导包
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        //建立List集合
        List<String> s=new ArrayList<>();//多态

        //向该集合添加信息值
        s.add("鸡");
        s.add("你");
        s.add("不");
        s.add("美");
        System.out.println(s);

        //1
        for (int i = 0; i < s.size(); i++) {
            String s1 = s.get(i);
            if (s1.equals("不")){
                s.add("太");//给元素最后添加 "太" 元素
            }
            System.out.println(s1);
        }
        System.out.println("---------");

        //我现在又想通过for增强型和Iterator迭代器来把集合最后一个"太"字去掉

        //2
        Iterator<String> ii = s.iterator();
        while (ii.hasNext()) {
            String ss = ii.next();
            if (ss.equals("太")){
                s.remove("太");//ConcurrentModificationException
            }
            System.out.println(ss);
        }

        //3
        for (String sf:s) {
            if (sf.equals("太")){
                s.remove("太");//ConcurrentModificationException
            }
            System.out.println(sf);
        }
    }
}

输出的内容:

[鸡, 你, 不, 美]



======================






Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList.Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList.Itr.next(ArrayList.java:859)
at CCom.Cnn.Demo.main(Demo.java:51)

ConcurrentModificationException

图文关系:
并发修改异常原理及原因
并发修改异常(迭代器在使用的时候,尽量不要使得集合的长度发生变化,也就是不能在迭代器中增删,但是改变位置元素的内容是可以的)
通俗的讲:

  • 迭代器在一个类里面遍历第二次集合,也会有这个并发异常出现
  • for增强型和iterator方法:实际修改次数与预期修改次数发生变化 (走私没有通知主人就跑进来)
  • 普通for:没有牵扯实际与预期的发生变化 (通过正常渠道进来的)

通过迭代器进行添加删除等元素改变修改次数的话,会出现异常ConcurrentModificationException,以下是原理源码

public interface List<E> {
    Iterator<E> iterator();
    boolean add(E e);
}
public abstract classAbstractList<E>{
protected int modCount = 0;
        }

public class ArrayList<E> extends AbstractList<E>implements List<E>{
    public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    public Iterator<E> iterator() {
        return new Itr();
    }
    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() {
            //modCount修改集合次数         expectedModCount预期修改集合次数
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
}
上一篇:vue的todoList案例


下一篇:Java入门---------集合(尚马day15)Week4(7)