读书人

为什么会出现 java.util.ConcurrentMo

发布时间: 2012-10-24 14:15:58 作者: rapoo

为什么会出现 java.util.ConcurrentModificationException 异常?
工作中碰到个concurrentmodificationexception。代码如下:

public abstract class abstractlist<e> extends abstractcollection<e> implements list<e> { //abstractcollection和list都继承了collection    protected transient int modcount = 0;    private class itr implements iterator<e> {  //内部类itr        int cursor = 0;        int lastret = -1;        int expectedmodcount = modcount;        public boolean hasnext() {            return cursor != size();        }        public e next() {            checkforcomodification();  //特别注意这个方法            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);  //执行remove对象的操作                if (lastret < cursor)                    cursor--;                lastret = -1;                expectedmodcount = modcount;  //重新设置了expectedmodcount的值,避免了concurrentmodificationexception的产生            } catch(indexoutofboundsexception e) {                throw new concurrentmodificationexception();            }        }        final void checkforcomodification() {            if (modcount != expectedmodcount)  //当expectedmodcount和modcount不相等时,就抛出concurrentmodificationexception                throw new concurrentmodificationexception();        }    }   }remove(object o)在arraylist中实现如下: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;}private void fastremove(int index) {    modcount++;  //只增加了modcount    ....}
?<span style="color: #0000ff;"><br><span style="color: #339966;"><br><strong style="color: #800000;">所以,产生concurrentmodificationexception的原因就是:<br>执行remove(object o)方法之后,modcount和expectedmodcount不相等了。然后当代码执行到next()方法时,判断了checkforcomodification(),发现两个数值不等,就抛出了该exception。<br>要避免这个exception,就应该使用remove()方法。</strong></span><br></span>这里我们就不看add(object o)方法了,也是同样的原因,但没有对应的add()方法。一般嘛,就另建一个list了<br><br><br>下面是网上的其他解释,更能从本质上解释原因:<br>iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 iterator 会马上抛出 java.util.concurrentmodificationexception 异常。<br>所以 iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 iterator 本身的方法 remove() 来删除对象, iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

读书人网 >编程

热点推荐