Deque remove 没有抛出 ConcurrentModificationException
Deque remove is not throwing ConcurrentModificationException
双端队列 class' 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. 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.
但是,以下程序的行为不同:
[编辑]: 我在粘贴整个代码时遇到错误 "An error occurred submitting the edit"。哇!来吧。
// 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
知道为什么吗?
看起来是因为你在删除它之前消耗了迭代器的第一个元素。如果您将代码更改为
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 中的以下段落:
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. 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.
双端队列 class' 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. 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.
但是,以下程序的行为不同:
[编辑]: 我在粘贴整个代码时遇到错误 "An error occurred submitting the edit"。哇!来吧。
// 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
知道为什么吗?
看起来是因为你在删除它之前消耗了迭代器的第一个元素。如果您将代码更改为
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 中的以下段落:
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. 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.