ConcurrentModificationException

ConcurrentModificationException

This question already has answers here:
Why is a ConcurrentModificationException thrown and how to debug it

(8个答案)



Why isn't this code causing a ConcurrentModificationException? [duplicate]

(4个答案)


在10个月前关闭。





以下代码不会引发ConcurrentModificationException

    public static void main(String[] args)
    {
        List<String> l1 = new ArrayList<>();
        l1.add("v1");
        Iterator<String> it =  l1.iterator();
        l1.remove(0);
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }


而此代码引发ConcurrentModificationException

    public static void main(String[] args)
    {
        List<String> l1 = new ArrayList<>();
        l1.add("v1");
        Iterator<String> it =  l1.iterator();
        l1.add("v2");
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }


这两个操作都是对list的结构修改,但是为什么仅在加法的情况下才抛出异常?

最佳答案

ArrayList.Itr

有两个计数器:ArrayList.modCountArrayList.Itr.expectedModCount。当ArrayList.ItrConcurrentModificationException抛出modCount != expectedModCount

这是对的。但是,如果您查看ArrayList.Itr.hasNext,则可以看到:

public boolean hasNext() {
    return cursor != size;
}


当您删除一个元素并且列表变为空时,您的代码将不会调用it.next()

为了使代码抛出ConcurrentModificationException,在while循环之前您应该没有空列表:

public static void main(String[] args)
{
    List<String> l1 = new ArrayList<>();
    l1.add("v1");
    l1.add("v2");
    Iterator<String> it =  l1.iterator();
    l1.remove(0);
    while(it.hasNext()) {
        System.out.println(it.next());  // --> ConcurrentModificationException
    }
}

关于java - 对于Java List,如果在迭代之前调用remove方法,则不会引发并发修改异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57563408/

10-10 22:55