[英]Deque remove is not throwing ConcurrentModificationException
The Deque class' Javadoc says: Deque类的Javadoc说:
The iterators returned by this class's iterator method are fail-fast: If the deque is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will generally throw a ConcurrentModificationException.
此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改了双端队列,则除了通过迭代器自己的remove方法之外,该迭代器通常会抛出ConcurrentModificationException。 Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
因此,面对并发修改,迭代器会快速干净地失败,而不会在未来的不确定时间内冒任意,不确定的行为的风险。
However, the below program behaves differently: 但是,以下程序的行为有所不同:
[EDIT]: I am getting error while pasting the whole code "An error occurred submitting the edit". [编辑]:粘贴整个代码“提交编辑时出错”时出现错误。 Whew!
呼! C'mon SO.
来吧
// create an empty array deque with an initial capacity
Deque deque = new ArrayDeque(8);
// use add() method to add elements in the deque
deque.add(15);
deque.add(22);
deque.add(25);
deque.add(20);
System.out.println("printing elements using iterator:");
for(Iterator itr = deque.iterator();itr.hasNext();) {
System.out.println(itr.next());
deque.remove(); //deque is modifed after the iterator is created
}
I expected it to throw ConcurrentModificationException
, but it simply prints the following output: 我希望它会抛出
ConcurrentModificationException
,但是它只是输出以下输出:
printing elements using iterator:
15
22
25
20
Any idea why? 知道为什么吗?
It looks like it's because you consume the first element of the iterator before removing it. 看起来是因为您在删除迭代器之前先消耗了它的第一个元素。 If you change your code to
如果您将代码更改为
for(Iterator itr = deque.iterator();itr.hasNext();) {
deque.remove();
System.out.println(itr.next());
}
then you'll see the exception. 那么您将看到异常。 Your original implementation does indeed contradict the documentation.
您的原始实现确实与文档相矛盾。
However, looking in the implementation of ArrayDeque's iterator implementation, the next() method has this code: 但是,在ArrayDeque的迭代器实现的实现中,next()方法具有以下代码:
E result = (E) elements[cursor];
// This check doesn't catch all possible comodifications,
// but does catch the ones that corrupt traversal
if (tail != fence || result == null)
throw new ConcurrentModificationException();
Note the following paragraph in the Deque's Javadoc : 请注意Deque的Javadoc中的以下段落:
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.
快速失败的迭代器会尽最大努力抛出ConcurrentModificationException。 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.
因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应仅用于检测错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.