我是靠谱客的博主 隐形毛豆,最近开发中收集的这篇文章主要介绍java集合--java.util.ConcurrentModificationException异常,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ConcurrentModificationException 异常并发修改异常,当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。一个线程对collection集合迭代,另一个线程对Collection进行修改的时候, 就会出现上面的异常.

下面看一下代码:

  

package cn.itcast.p4.list.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListIteratorException {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String>list = new ArrayList<String>();
list.add("abc1");
list.add("abc2");
list.add("abc3");
list.add("abc4");
Iterator it = list.iterator();
while(it.hasNext()){
String s = (String) it.next();
if(s.equals("abc2")){
list.remove(s);
}else{
System.out.println(s);
}
}
System.out.println(list);
}
}

 

 

 

运行结果:

abc1
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at cn.itcast.p4.list.demo.ListIteratorException.main(ListIteratorException.java:22)


list.iterator()方法的源码:

public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous.
Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have.
If this expectation is violated, the iterator
* has detected concurrent modification.
通过看API AbstractList.class 发现该类里面有一个成员变量: protected transient int modCount = 0;
是不可被序列化的变量,当对集合进行add,remove,removeRange,addAll等修改动作的时候,没操作一次,modCount加1。
用来记录对集合修改的次数。

*/ int expectedModCount = modCount;//上面因为翻译过来,为迭代器的expectedModCount值和List集合中的modCount 初始值一致 public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification();//每调用一次next方法,都要通过此方法检测expectedModCount(迭代对象的后) try { E next = get(cursor); lastRet = cursor++; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } //用来检测现在的List中的modCount与创建迭代器的时候初始expectedModCount值是否想相等,不相等,返回异常ConcurrentModificationException final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }

可能大家对modCount还不明白,再看下AbstractList.Class里面的源代码:

 

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
protected transient int modCount = 0;
class SubList<E> extends AbstractList<E> {
。。。。。。。。省略很多代码。。。。。。。。。。。。。
public void add(int index, E element) {
if (index<0 || index>size)
throw new IndexOutOfBoundsException();
checkForComodification();
l.add(index+offset, element);
expectedModCount = l.modCount;
size++;
  modCount++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = l.remove(index+offset);
expectedModCount = l.modCount;
size--;

 modCount++;
return result;
}
}
}

 

分析上面的源代码:

 


通过看API AbstractList.class 发现该类里面有一个成员变量: protected transient int modCount = 0, 是不可被序列化的变量,当对集合
进行add,remove,removeRange,addAll等修改动作的时候,每修改一次,modCount加1。用来记录对集合修改的次数

private class Itr 类里面有一个成员变量expectedModCount初始值和List中的modCount一样,只要在迭代的过程中线程没有对List集合进行
上面的修改动作,modCount值就不会变。那么expectedModCount=modCount条件始终成立,checkForComodification检测集合是否被修改的
方法里面的if判断不成立,不会抛出异常。
但是在我们的程序中,执行到list.remove(s);时候,一个线程对集合进行it.next()遍历,一个线程对集合进行remove动作,这样当删除"abc2"对象后,
list对象的成员变量modCount的值+1,但是迭代对象Itr 里面的expectedModCount不变,所以两个值不
相等,等再次调用next()方法后,
调用checkForComodification方法,if条件成立,这样就抛出了异常。

 

 

转载于:https://www.cnblogs.com/200911/p/3946870.html

最后

以上就是隐形毛豆为你收集整理的java集合--java.util.ConcurrentModificationException异常的全部内容,希望文章能够帮你解决java集合--java.util.ConcurrentModificationException异常所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部