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
知道为什么吗?
答案 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。因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应仅用于检测错误。