java.util.ConcurrentModificationException异常原因及解决方法
通过错误提示,知道了异常出现在checkForComodification这个方法上,异常原因是modCount!在网上查询得知,在很多容器中,都有一个变量记录你从结构上修改此容器的次数,叫做modCount,查看ArrayList的add()和remove()方法就可以发现,每次你调用add方法()向容器里面增加了一个元素,或者你调用Remove()方法删除了其中的某个元素,这个值都会增加1。
问题描述
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBCEkCAp-1664620566645)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001110837376.png)]](https://i-blog.csdnimg.cn/blog_migrate/e817fb29f728a85af40cf1df31b31a13.png)
通过错误提示,知道了异常出现在checkForComodification这个方法上,异常原因是modCount != expectedModCount
在网上查询得知,在很多容器中,都有一个变量记录你从结构上修改此容器的次数,叫做modCount,查看ArrayList的add()和remove()方法就可以发现,每次你调用add方法()向容器里面增加了一个元素,或者你调用Remove()方法删除了其中的某个元素,这个值都会增加1。在对集合进行迭代的时候,这个值不能被改变,否则抛出异常ConcurrentModificationException。简单地说就是你在遍历的时候,你自己不会去改变这个值,但是你在遍历的过程中发现这个值被改变了,那只有一种解释,其他人修改了集合导致这个值改变了。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-spDrSXQd-1664620566646)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001115507225.png)]](https://i-blog.csdnimg.cn/blog_migrate/3a8fe0eabdac5b407c54e5dba8ddffab.png)
而expectedModCount表示的是list容器被修改的次数的期望值,它的初始值为modCount
出现原因

我们先根据程序的代码一步一步看ArrayList源码的实现:
首先看ArrayList的iterator()方法,源码如下:
从源码上可以看出iterator()方法返回的是一个指向Itr类型对象的引用,iterator的实现,在AbstractList类中可以中找到Itr类的具体实现
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FDf3KObm-1664620566647)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001172011407.png)]](https://i-blog.csdnimg.cn/blog_migrate/e8b180a9d4ecd527656b904671bd4665.png)
每次循环都会经过两步操作,第一步是iterator.hasNext() ,判断是否有下一个元素;当我们调用list.Iterator()返回一个Iterator之后,会通过Iterator的hashNext()方法判断是否还有元素未被访问
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hfn3XuUV-1664620566647)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001172303908.png)]](https://i-blog.csdnimg.cn/blog_migrate/c52062acbe2de36405558db85b1986e9.png)
第二步是iterator.next(),判断下一个元素是什么,并且进行赋值操作;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fEEQMrEu-1664620566647)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001172502327.png)]](https://i-blog.csdnimg.cn/blog_migrate/8c285ad7429cf0d7b3825a6a2c272ef3.png)
可以发现,在next方法中会调用checkForComodification方法,在checkForComodification()方法中,判断了modCount和expectedModCount是否相等。如果不相等,就会抛出我们遇到的这个异常。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0vFviHpg-1664620566648)(C:/Users/19444/AppData/Roaming/Typora/typora-user-images/image-20221001182222166.png)]](https://i-blog.csdnimg.cn/blog_migrate/aa7dd6262929738fa1c002291670bbc7.png)
解决办法
1、new Vector<>()
2、Collections.synchronizedList(new ArrayList<>());
使用的是Collections工具包
3、new CopyOnWriteArrayList<>();
写时复制copyOnWrite容器即写时复制的容器往容器添加元素的时候,不直接往当前容器object[]添加,而是先将当前容器object[]进行copy,复制出一个新的object[] newElements然后向新容器object[] newElements里面添加元素 添加元素后,再将原容器的引用指向新的容器setArray(newElements);
这样的好处是可以对copyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何容器,所以copyOnwrite容器也是一种读写分离的思想,读和写不同的容器
更多推荐




所有评论(0)