【问题标题】:Problems with ListIterator and Concurrent Modification ExceptionListIterator 和并发修改异常的问题
【发布时间】:2012-03-14 08:26:44
【问题描述】:

我有两个 ArrayList,每个都包含一定大小的块:blockList、eraseList。块是具有两个字段的对象:开始和结束。我需要从另一组块中减去一组块。

我必须遍历擦除器列表并从块列表中“擦除”它们重叠的块。因此我的代码如下所示:

 void eraseBlocks (Arrylist<Blocks> blockList, ArrayList<Blocks> eraserList) {
    ListIterator<Blocks> it = blockList.listIterator();

    for (Blocks eraser: eraserList) {
        while (it.hasNext()) {
            Blocks block= it.next();
            if ((eraser.start <= block.start) && (eraser.end >= block.end))
                 blockList.remove(block);
            else if ((eraser.start <= block.start) && (eraser.end < block.end)){
                 block.set(start, eraser.end);
            else if () {
                        ...
                 //more code for where the eraser partially erases the beginning, end, or splits the block
                 //if statements call the .add(), .set(), and remove() methods on the blockList.
                        ...
                  }
            }
        }

我不明白为什么会出现并发修改异常。我从不修改橡皮擦列表。

我正在尝试修改在“Block block = it.next();”中分配的块对象陈述。我还通过在列表中删除或添加块来修改 blockList。我认为 ListIterator 的全部意义在于它允许您修改、添加或减去您正在浏览的列表。

Failure Trace 指向 Blocks eraser = it.next();作为画线的异常,但我不知道那告诉我什么。

谁能帮我弄清楚我做错了什么?

谢谢!

【问题讨论】:

  • 您正在修改 blockList ......您可以对迭代器进行的唯一修改是调用 it.remove(),它会从列表中删除当前项目。对列表本身的任何操作都会导致并发修改异常。

标签: java arraylist iterator


【解决方案1】:

是的,ListIterator 旨在允许修改列表。但是您没有使用 ListIterator 的 remove() 方法,而是直接操作底层列表本身。

【讨论】:

  • 同样的警告适用于似乎被注释掉的add 操作。
  • 谢谢。我想将新项目添加到列表中的唯一方法是将它们累积在一个临时列表中,并在循环完成后执行 addAll。
【解决方案2】:

替换

blockList.remove(block);

it.remove();

如果您以其他方式移除元素,您可以获得 CME。

【讨论】:

    【解决方案3】:

    您需要拨打remove()Iterator,而不是List

    来自 javadoc:

    如果单个线程发出一系列方法调用, 违反了对象的约定,对象可能会抛出这个 例外。例如,如果一个线程直接修改一个集合 当它使用快速失败的迭代器迭代集合时, 迭代器会抛出这个异常。

    【讨论】:

      猜你喜欢
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多