并发修改异常的源码分析

并发修改异常:ConcurrentModificationException

产生原因:迭代器遍历过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致

解决方案:用for循环遍历,然后用集合对象做对应操作即可

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
需求:
    我有一个集合: List<String> list = new ArrayList<String>();
    里面有三个元素: list. add( "hello");list. add( "world");list. add( "java");
    遍历集合,得到每一个元素,看有没有"world"这个元素,如果有,我就添加一个"javaee“元素,请写代码实现

    //ConcurrentModificationException:当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。
 */
public class ListDemo_1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("hello");
        list.add("world");
        list.add("java");

        Iterator<String> it=list.iterator();

//while循环遍历
// while (it.hasNext()){ // String s=it.next();//ConcurrentModificationException:并发修改异常  //① // if (s.equals("world")){ // list.add("javaee"); // } // }


//for循环遍历
for (int i = 0; i < list.size(); i++) { String s=list.get(i); if (s.equals("world")){ list.add("javaee"); } } System.out.println(list);  //[hello, world, java, javaee] } }

并发修改异常源码分析

public interface List<E>{
    Iterator<E> iterator();
    boolean add(E e);
}

public abstract class AbstractList<E>{
    protected int modCount=0;//:③-1此处定义modCount初始值
}

public class ArrayList<E> extends AbstractList<E> implements List<E>{
    public E get(int index) {//⑤:修改后:没有实际修改值和预期修改值的判断,故不会抛出异常
        Objects.checkIndex(index, size);
        return elementData(index);
    }
    public boolean add(E e) {//③:调用add(),中modCount数值改变。原本数值是ArrayList继承的父类中的属性值=0。
            modCount++;
            add(e, elementData, size);
            return true;
        }

    public Iterator<E> iterator() {
        return new Itr();
    }

     private class Itr implements Iterator<E> {

        int expectedModCount = modCount;
        /*
        modCount:实际修改结合的次数
        expectedModCount:预期修改集合的次数
        */


        public E next() {//②:调用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();
        }

     }
}

 

posted @ 2022-01-30 16:46  打烊宠烊  阅读(51)  评论(0)    收藏  举报