首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的并发修改异常

问Java中的并发修改异常
EN

Stack Overflow用户
提问于 2012-11-09 19:42:46
回答 4查看 10.6K关注 0票数 3

我在执行这段代码时得到了ConcurrentModificationException。我不明白为什么会发生这样的事情?

代码语言:javascript
复制
private void verifyBookingIfAvailable(ArrayList<Integer> list, int id) {

        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
                int value = iterator.next();
                if (value == id) {
                    int index = list.indexOf(id);

                    if (index != -1) {
                        list.remove(index);
                    }
                }
        }
    }

提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-09 19:44:40

您正在使用list引用本身删除列表中的元素,这会抛出ConcurrentModificationException。请注意,这可能有时会起作用,但并不总是如此,并且不能保证完美地工作。

此外,即使您使用Iterator来迭代列表,您仍然不应该使用list.remove,您应该只使用iterator.remove()来删除元素,否则无论您使用迭代器还是增强的for-loop,这都不会有任何区别。

因此,使用iterator.remove()删除元素。

代码语言:javascript
复制
if (index != -1) {
    iterator.remove(value);
}

请参阅此帖子:- java-efficient-equivalent-to-removing-while-iterating-a-collection以获取更详细的解释。

票数 11
EN

Stack Overflow用户

发布于 2012-11-09 19:45:33

很简单,因为您试图在迭代元素时从ArrayList中删除这些元素。要解决此问题,请使用java.util.concurrent.CopyOnWriteArrayList。希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2012-11-09 19:45:36

发生的情况是,ArrayList迭代器并不是设计为在迭代时启用修改。

因此,为了避免来自不连贯数据的更严重的错误,它有一个修改计数,当你删除一个项目时,它会更新,当你迭代时,它会进行检查:

来自ArrayList.java:

代码语言:javascript
复制
411     public E remove(int index) {
412         rangeCheck(index);
413 
414         modCount++;
415         E oldValue = elementData(index);
416 
417         int numMoved = size - index - 1;
418         if (numMoved > 0)
419             System.arraycopy(elementData, index+1, elementData, index,
420                              numMoved);
421         elementData[--size] = null; // Let gc do its work
422 
423         return oldValue;
424     }
     ...
779 
780         final void checkForComodification() {
781             if (modCount != expectedModCount)
782                 throw new ConcurrentModificationException();
783         }

在javadoc中指定:

返回的列表迭代器是快速失败的。

要避免此问题,请使用迭代器删除当前元素,而不是直接删除列表。迭代器的remove方法确保迭代器保持一致。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13307471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档