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

java快速失败分析

2015-10-01 10:55 429 查看
首先,上单线程版的。

import java.util.ArrayList;
import java.util.Iterator;

public class ConcurrentModification {

public static void main(String[] args) {

ArrayList<Integer> list=new ArrayList();
for(int i=0;i<10;i++)
{
list.add(i);
}
Iterator it=list.iterator();
while(it.hasNext())
{
System.out.println(it.next());
list.remove(it.next());
}
}
}


java源码解析:

AbstractList$Itr

<span style="font-size:18px;">	final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}</span>


这个方法被遍历系列调用(next、previous),也会被修改系列方法调用(add、remove、set)。

modCount为实际修改次数,expectedModCount为期望修改次数。如果实际修改次数不等于期望修改次数的话,就会抛出如上异常。

那么我们看看next()方法:

<span style="font-size:18px;">   public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}</span>


而fastRemove()方法代码如下:

<span style="font-size:18px;">    /*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
}</span>


很显然,只修改了modCount,但是expectedModCount并未变,那么到下一个next()方法时就会出现不一致,抛出异常。

至于避免的方法有两种:

Collections.synchronizedList()方法

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