是否抛出 ConcurrentModificationException 取决于系统

发布于 2024-11-08 10:50:27 字数 525 浏览 0 评论 0原文

我正在使用 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 中运行此代码时,迭代器的下一个方法不会抛出任何异常。那么,并发修改异常是否取决于操作系统级别?

I am working on a piece of code with Iterator and getting a ConcurrentModificationException at the line a when I run the program from my IDE on windows--

  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++;
   }

This is expected because Im modifying the list while I'm iterating so the fail-fast iterator throws a Concurrentmodification exception. However, when I run this code in unix with apache server, the next method of the iterator does-not throw any exception. So, does the concurrentmodification exception depend on OS level ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

后知后觉 2024-11-15 10:50:27

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

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

操作系统与它无关。

No, it shouldn't. It should crash anyway.

I suppose it could be different on a different JVM, but according to the official spec, iterators on linked list should be fail-fast.

OS has nothing to do with it.

贵在坚持 2024-11-15 10:50:27

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

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

无论如何都不依赖于操作系统 - 使用 iter.remove() - 它将从底层列表中删除元素而不会导致异常。

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

I found out what the issue might be. When your list has 2 elements, the hasNext() returns false and it works without an exception. If the list has 3 or more elements it throws an exception everywhere. So make sure your list has the right number of elements.

As for the OS dependence - java code is not OS dependent

Anyway - use iter.remove() - it will remove the element from the underlying list without causing the exception.

The problem with your approach is that you are modifying the underlying list without the iterator knowing anything of that modification. So you have to carry it out via the iterator.

一页 2024-11-15 10:50:27

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

它确实有一些 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() ,则应始终抛出异常/代码>。

So, does the concurrentmodification
exception depend on OS level ?

It does have some JMV-dependence, but not in the code you showed.

// 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++;
}

When the list is accessed and iterated in different threads without proper synchronization, the modification made to LinkedList.modCount (when LinkedList.add, LinkedList.remove etc are called) might not be visible to the thread doing the iteration. So ConcurrentModificationExceptions are not guaranteed to be thrown, in general. But in the single-threaded code you showed, there should be no visibility problems and the exception should always be thrown if ll.remove() is ever called successfully after ll.iterator().

怼怹恏 2024-11-15 10:50:27

使用 iter.remove() ; not ll.remove(i)

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

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

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

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

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

If you use the iterator remove function, you will not get a concurrentmodificationexception.

However, to answer your question; the CME should not depend on OS level. There must be some other issue with your code as to why it is not throwing CME in unix.

BTW, the spec has the following comments

"Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文