您的位置:首页 > 编程语言 > Java开发

java源码分析(12)-ConcurrentModificationException

2016-07-06 23:01 423 查看
ConcurrentModificationException

此异常在使用迭代器时经常出现,主要原因为迭代器迭代未完成之前,容器属性被更改。例如下面的一段程序:



public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator=list.iterator();
while(iterator.hasNext()){
Integer i=iterator.next();
if(i==1){
list.remove(i);
}
}

}
如上图的代码所示,便会报ConcurrentModificationException异常,原因为在使用迭代器时,又使用了list的remove方法,使list的属性发生了变化,但却通知迭代器,迭代器在下次循环时发现容器属性发生变化而报错。下面请看源码

</pre><pre name="code" class="java">public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; //迭代器next指向的下标
int lastRet = -1; //现在指向的下标
int expectedModCount = modCount;//modCount为AbstractList中定义的属性,用于记录list被更改

的次数
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();//用于确认容器的属性是否发生变化(未通知迭代器的属性改变)
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;//可以看到迭代器中的remove方法在移除元素后,还将修改后的modCount通知了迭代器,使迭代过程中的list属性保持一致
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

final void checkForComodification() {
if (modCount != expectedModCount)//判断有效性,在迭代过程中,若出现非迭代器更改list的情况,将会抛异常以此来保证list属性的一致性
throw new ConcurrentModificationException();
}
}


所以,在使用迭代器时,若需要移除数据,请使用迭代器的remove方法,程序代码改为以下即可:
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator=list.iterator();
while(iterator.hasNext()){
Integer i=iterator.next();
if(i==1){
iterator.remove();
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: