是否抛出 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 中运行此代码时,迭代器的下一个方法不会抛出任何异常。那么,并发修改异常是否取决于操作系统级别?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,不应该。无论如何它应该崩溃。
我想它在不同的 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.
我发现问题可能是什么。当列表有 2 个元素时,
hasNext()
返回false
并且它可以正常工作。如果列表有 3 个或更多元素,则会在各处抛出异常。因此,请确保您的列表具有正确数量的元素。至于操作系统依赖性 - java 代码
无论如何都不依赖于操作系统 - 使用 iter.remove() - 它将从底层列表中删除元素而不会导致异常。
您的方法的问题在于您正在修改基础列表,而迭代器不知道该修改的任何内容。所以你必须通过迭代器来执行它。
I found out what the issue might be. When your list has 2 elements, the
hasNext()
returnsfalse
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.
它确实有一些 JMV 依赖性,但不在您展示的代码中。
当在不同线程中访问和迭代列表而没有正确同步时,对
LinkedList.modCount
进行的修改(当LinkedList.add
、LinkedList.remove
> 等被调用)可能对执行迭代的线程不可见。因此,一般来说,不保证会抛出 ConcurrentModificationException。但在您展示的单线程代码中,不应该出现可见性问题,并且如果在ll.iterator()< 之后成功调用
ll.remove()
,则应始终抛出异常/代码>。It does have some JMV-dependence, but not in the code you showed.
When the list is accessed and iterated in different threads without proper synchronization, the modification made to
LinkedList.modCount
(whenLinkedList.add
,LinkedList.remove
etc are called) might not be visible to the thread doing the iteration. SoConcurrentModificationException
s 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 ifll.remove()
is ever called successfully afterll.iterator()
.使用 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."