我正在使用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++;
}
这是预期的,因为我在迭代时修改列表,因此失败快速迭代器会抛出Concurrentmodification异常。但是,当我在unix中使用apache服务器运行此代码时,迭代器的下一个方法不会抛出任何异常。那么,并发修改例外是否依赖于操作系统级别?
答案 0 :(得分:3)
答案 1 :(得分:1)
我发现了问题所在。当您的列表包含2个元素时,hasNext()
会返回false
,并且无异常。如果列表包含3个或更多元素,则会在任何地方抛出异常。因此,请确保您的列表中包含正确数量的元素。
至于操作系统依赖性 - java代码不依赖于操作系统
无论如何 - 使用iter.remove()
- 它会从基础列表中删除元素而不会导致异常。
您的方法的问题是您正在修改基础列表,而迭代器不知道该修改的任何内容。所以你必须通过迭代器来实现它。
答案 2 :(得分:0)
使用iter.remove();不是ll.remove(i)
如果使用迭代器删除函数,则不会出现并发修改。
然而,要回答你的问题; CME不应该依赖于操作系统级别。您的代码必须存在其他问题,以确定它不会在unix中抛出CME。
顺便说一句,该规范有以下评论“请注意,迭代器的快速失败行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬性保证。失败快速的迭代器会尽最大努力抛出ConcurrentModificationException因此,编写一个依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应仅用于检测错误。“
答案 3 :(得分:0)
那么,并发修改 异常取决于操作系统级别?
它确实有一些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.add
,LinkedList.remove
等被调用时)的修改可能对线程不可见做迭代。所以ConcurrentModificationException
一般都不能保证被抛出。但是在您展示的单线程代码中,应该没有可见性问题,如果在ll.remove()
之后成功调用ll.iterator()
,则应始终抛出异常。