1、既然大家都是点进来解决问题的,那么我首先先说下最便捷的解决方案吧,无论您是多线程报错,还是for循环中删除报错,只需用CopyOnWriteArrayList来替换普通的ArrayList,那就一定不会报错了。如下图所示:
2、另外如果您是在for循环中使用arraylist自带的remove删除的话,有另外的解决方案,就是使用iterator的remove函数,或者for循环不使用for each形式,而是使用i为标志位,删除的时候记得标注为--,在计算。
3、问题想必各位都已经解决了,接下来我再继续补充一下fail-fast产生错误的原因。需要注意的是,fail-fast只是一个错误检测机制,并不代表有错误一定会触发这个机制。
4、触发这个原因在于list本身存在一个list的长度,但是为了保持一致性,仅仅是长度上的一致性,多存了一个list的长度,存在另外一个变量中。这两个变量分别是‘expectedModCount’和‘modCount’,只有在构建iterator的时候才会expectedModCount =modCount初始化,但是如果构建完毕正在读取中,modCount发生了不一致,那么就会报错
5、那么modCount在什么时候会产生变化痒滕熘丬呢,正如我前面说的,这个是为了保持长度一致性所以才建立的,因此飧肇苡卫只要list的长度发生变化了,这个值就会发生变化,也就是当你已经构建完毕iterator的时候,如果在其他线程增删,恰好异步到这个位置,或者说你根本没有使用iterator的删除函数,而是直接采用了list自带的remove就会产生这样子的结果。
6、相信细心的读者已经看出来了,这个监测只监测长度,因此只要在next被执行之前,也就是判断这两个值是否相等之前,不管发生了什么变动,只要保证开始next的时候这个arraylist长度不变,那么就不会报错。因此这个检测并不能排错,只是错误的预警而已。