java.util.ConcurrentModificationException异常原因及解决方法
通过错误提示,知道了异常出现在checkForComodification这个方法上,异常原因是modCount!在网上查询得知,在很多容器中,都有一个变量记录你从结构上修改此容器的次数,叫做modCount,查看ArrayList的add()和remove()方法就可以发现,每次你调用add方法()向容器里面增加了一个元素,或者你调用Remove()方法删除了其中的某个元素,这个值都会增加1。
问题描述
通过错误提示,知道了异常出现在checkForComodification这个方法上,异常原因是modCount != expectedModCount
在网上查询得知,在很多容器中,都有一个变量记录你从结构上修改此容器的次数,叫做modCount,查看ArrayList的add()和remove()方法就可以发现,每次你调用add方法()向容器里面增加了一个元素,或者你调用Remove()方法删除了其中的某个元素,这个值都会增加1。在对集合进行迭代的时候,这个值不能被改变,否则抛出异常ConcurrentModificationException。简单地说就是你在遍历的时候,你自己不会去改变这个值,但是你在遍历的过程中发现这个值被改变了,那只有一种解释,其他人修改了集合导致这个值改变了。
而expectedModCount表示的是list容器被修改的次数的期望值,它的初始值为modCount
出现原因
我们先根据程序的代码一步一步看ArrayList
源码的实现:
首先看ArrayList的iterator()方法,源码如下:
从源码上可以看出iterator()方法返回的是一个指向Itr类型对象的引用,iterator的实现,在AbstractList类中可以中找到Itr类的具体实现
每次循环都会经过两步操作,第一步是iterator.hasNext() ,判断是否有下一个元素;当我们调用list.Iterator()返回一个Iterator之后,会通过Iterator的hashNext()方法判断是否还有元素未被访问
第二步是iterator.next(),判断下一个元素是什么,并且进行赋值操作;
可以发现,在next方法中会调用checkForComodification方法,在checkForComodification()方法中,判断了modCount和expectedModCount是否相等。如果不相等,就会抛出我们遇到的这个异常。
解决办法
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)