一、应用背景

在阿里巴巴开发手册中,有这样一条规定:不要在foreach循环里进行add和remove操作(这里指的是List的add和remove操作),否则会抛出ConcurrentModificationException。remove元素请应用iterator。

二、源码

1.咱们晓得foreach是语法糖,他实质还是iterator进行的循环,因而上面的代码和应用foreach循环是一样的。在循环外面咱们应用“谬误”操作,应用List的add办法进行操作,会抛出ConcurrentModificationException

       ArrayList<String> arrayList = new ArrayList<>();        arrayList.add("apple");        Iterator<String> iterator = arrayList.iterator();        while(iterator.hasNext()){            String value = iterator.next();            if("apple".equals(value)){                arrayList.add("orange");            }        }

三、源码解析

1.arrayList.iterator();

①返回Itr类,并将modcount的值赋值给一个变量expectedModCount,其中modcount示意List理论被增删的次数,expectedModCount示意该迭代器冀望被增删的次数,当新建Itr类的时候会给他赋初始值,只有通过该迭代器进行值的增删才会批改该值

2.iterator.next();

①在调用迭代器的next办法时,他会进行查看,比拟modCount和expectedModCount的值,如果不相等,Concurrent

四、总结

1.modCount和expectedModeCount不统一才会抛出ConcurrentModificationException。当咱们调用List的remove办法时,他只会批改modCount的值;当咱们调用iterator的remove办法,他会将modCount的值赋值给expectedModeCount

2.modCount和expectedModeCount是属于fast-fail机制,用于多线程中,当进行遍历的时候,有其余线程批改值的时候就会进行查看

五、解决办法

1.应用一般for循环进行操作

2.在循环中应用iterator进行操作

3.应用stream流进行过滤

4.应用fast-saft平安的类,如ConCurrentLinkedQueue