是否抛出 ConcurrentModificationException 系统依赖于



我正在使用Iterator处理一段代码,并在Windows上从IDE运行程序时在a行获得ConcurrentModificationException--

  LinkedList ll =new LinkedList();
  . . .
  . . . 
  Iterator iter = ll.iterator();
  int i=0;
   while (iter.hasNext()) {
       // GrammarSection agrammarSection = (GrammarSection) iter.next();  //a
       String s1 = (String) iter.next();
        ll.remove(i);
        i++;
   }

这是意料之中的,因为我在迭代时修改了列表,因此故障快速迭代器会引发并发修改异常。但是,当我使用 apache 服务器在 unix 中运行此代码时,迭代器的下一个方法不会引发任何异常。那么,并发修改异常是否取决于操作系统级别?

不,不应该。 无论如何,它应该崩溃。

我想在不同的 JVM 上可能会有所不同,但根据官方规范,链表上的迭代器应该是快速失败的。

操作系统与它无关。

我发现了问题可能是什么。当您的列表有 2 个元素时,hasNext() 返回 false 并且它无一例外地工作。如果列表有 3 个或更多元素,则会在任何地方抛出异常。因此,请确保您的列表具有正确数量的元素。

至于操作系统依赖性 - java代码不依赖于操作系统

无论如何 - 使用 iter.remove() - 它将从基础列表中删除元素而不会导致异常。

您的方法的问题在于,您正在修改基础列表,而迭代器不知道该修改的任何内容。因此,您必须通过迭代器执行它。

那么,并发修改是否 异常取决于操作系统级别?

它确实有一些 JMV 依赖性,但不在您显示的代码中。

// LinkedLists have a member variable called modCount
// which is an integer which holds the count of modifications
// made on the list with methods like list.add() list.remove() etc.
LinkedList ll =new LinkedList();
. . .
. . . 
// When the iterator is created here, it copies the current modCount
// of the LinkedList into a member of its own called expectedModCount
Iterator iter = ll.iterator();
int i= 0;
while (iter.hasNext()) {
    // iter.next() calls a method called checkForComodification
    // which throws a ConcurrentModificationException if the
    // current modCount of the original LinkedList is different
    // from the expectedModCount on this iterator
    String s1 = (String) iter.next();
    ll.remove(i);
    i++;
}

当在不同的线程中访问和迭代列表而没有正确同步时,对LinkedList.modCount所做的修改(调用 LinkedList.addLinkedList.remove 等时)可能对执行迭代的线程不可见。所以一般来说,ConcurrentModificationException不能保证被扔掉。但是在您展示的单线程代码中,应该没有可见性问题,如果在 ll.iterator() 之后成功调用ll.remove(),则应始终抛出异常。

use iter.remove() ; not ll.remove(i)

如果使用迭代器 remove 函数,则不会得到并发修改异常。

但是,要回答您的问题;CME不应依赖于操作系统级别。你的代码一定还有其他一些问题,为什么它没有在 unix 中抛出 CME。

顺便说一句,该规范有以下评论

"请注意,迭代器的快速故障行为无法保证,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。Fail-fast 迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖于此异常的正确性的程序是错误的:迭代器的快速故障行为应该仅用于检测错误。

最新更新