简体   繁体   English

双端队列删除未引发ConcurrentModificationException

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM