Deque删除不会抛出ConcurrentModificationException

时间:2015-04-21 10:49:14

标签: java iterator deque

Deque班级'Javadoc说:

  

此类的迭代器方法返回的迭代器是快速失败的:   如果在创建迭代器后的任何时间修改了deque,请执行   除了通过迭代器自己的remove方法之外的任何方式,迭代器   通常会抛出一个ConcurrentModificationException。因此,在   面对并发修改,迭代器很快就失败了   干净利落,而不是冒着任意的,非确定性的行为冒险   未来不确定的时间。

但是,以下程序的行为有所不同:

[编辑]:我在粘贴整个代码时遇到错误“提交编辑时出错”。呼!来吧。

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

我希望它抛出ConcurrentModificationException,但它只是输出以下输出:

printing elements using iterator:
15
22
25
20   

知道为什么吗?

1 个答案:

答案 0 :(得分:1)

它看起来像是因为你在删除它之前使用了迭代器的第一个元素。如果您将代码更改为

for(Iterator itr = deque.iterator();itr.hasNext();)  {
    deque.remove(); 
    System.out.println(itr.next());
}

然后你会看到异常。您的原始实现确实与文档相矛盾。

但是,查看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();

请注意Deque's Javadoc中的以下段落:

  

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