小编典典

CopyOnWriteArrayList抛出CurrentModificationException

java

ConcurrentModificationException当我遍历列表时,偶尔会得到一个。Google搜索通知我,这可能是因为我在迭代该列表时正在另一个线程中更改该列表,并且要使此问题消失,我应该使用java.util.concurrent.CopyOnWriteArrayList…。

…除了我已经是。

显然,我在某处正在做一些 非常 愚蠢的事情。

是否有人对如何引发CopyOnWriteArrayList抛掷物有任何见识ConcurrentModificationException?如果有关系,我正在使用Java
5。

编辑: 由于我使用的转换器可能很重要,因此我以两种方式修改此列表:

  • 在前面添加元素。(list.add(0, newElement);
  • 使用subList让较旧的项目掉下来。(list = list.subList(0, MAX_LIST_SIZE);

那些举起红旗吗?如果是这样,为什么?我的理解是,因为这些操作首先复制了事物,所以任何现有的迭代器都将指向未修改的原始对象,因此将不在乎。我的知识有漏洞吗?

编辑2: 导致问题的精确代码仍然有点模糊,但是我至少可以发布我看到的异常:

java.util.ConcurrentModificationException
    at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source)
    at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source)
    at....

…它指向我的代码中的for-each循环实例。

COWSubList似乎暗示着我的呼吁subList是问题的根源。我仍然想了解为什么。

编辑3:* facepalm ***

CopyOnWriteArrayList.subList()返回一个List不是
一个CopyOnWriteArrayList。它返回的列表不承担任何COWAL保护的隐含义务。这使得subList()像这样删除元素是一个非常糟糕的主意。

不确定这是否是我的罪魁祸首,但该死的可疑之处无论如何都需要纠正。


阅读 220

收藏
2020-09-26

共1个答案

小编典典

如果包含列表从其下方更改,则CopyOnWriteArrayList.subLists会引发ConcurrentModificationExceptions:

public class ListTest {

  private static List<int[]> intList;

  public static void main (String[] args) {
    CopyOnWriteArrayList<Integer> cowal = new CopyOnWriteArrayList<Integer>();
    cowal.add(1);
    cowal.add(2);
    cowal.add(3);

    List<Integer> sub = cowal.subList(1, 2);
    cowal.add(4);
    sub.get(0); //throws ConcurrentModificationException
  }
}
2020-09-26