[英]How Java iterators detect the collection is modified to throw ConcurrentModificationException?
How Java iterators detect the collection is modified? Java 迭代器如何检测集合被修改? Tried to search, found:
试图搜索,发现:
Usually the traditional collection classes in java.util package uses an int variable (modCount) to keep track of modifications (additions and deletions).
通常 java.util package 中的传统集合类使用一个 int 变量 (modCount) 来跟踪修改(添加和删除)。
When we ask for an Iterator from these collection classes then a object of Iterator which is returned is provided with the existing modification count variable as its expected modification count.
当我们从这些集合类中请求 Iterator 时,返回的 Iterator 的 object 将提供现有的修改计数变量作为其预期的修改计数。
Upon invoking the next() method the Iterator object checks the current modification count variable value against its expected modification count value.
在调用 next() 方法时,迭代器 object 会根据预期的修改计数值检查当前修改计数变量值。
In case of a mismatch it fails fast by throwing ConcurrentModificationException present in java.util package, its a RuntimeException.
在不匹配的情况下,它会通过抛出 java.util package 中存在的 ConcurrentModificationException 快速失败,这是一个 RuntimeException。
But what if we但是如果我们
? ?
It seems everything OK with 2nd iterator, isn't it?使用第二个迭代器似乎一切正常,不是吗? So how about modCount then?
那么 modCount 呢? The modified collection should inform the 1st iterator to throw the exception and at the same time shouldn't inform the 2nd.
修改后的集合应该通知第一个迭代器抛出异常,同时不应该通知第二个。 Explain please how modCount works?
请解释一下 modCount 是如何工作的? It should be challenge to program modCount's behavior or keep a collection of modCounts for each iterator.
对 modCount 的行为进行编程或为每个迭代器保留 modCounts 的集合应该是一个挑战。 Anyway clarify please how multiple iterators validate their consistency simultaneously and independently?
无论如何,请澄清多个迭代器如何同时独立地验证它们的一致性?
Generally, it works like this:一般来说,它是这样工作的:
class MyCollection implements Collection<E /* or whatever the elements are */> {
private int modCount = 0;
private class MyIterator implements Iterator<E> {
private int expectedModCount;
public MyIterator() {
expectedModCount = modCount;
}
@Override
public E next() {
if(expectedModCount != modCount) throw new ConcurrentModificationException();
}
// etc.
}
@Override
public Iterator<E> iterator() {
return new MyIterator();
}
@Override
public boolean add(E e) {
modCount++;
// etc.
}
// etc.
}
Each MyIterator
knows what modCount
to expect, remembering the value as a field.每个
MyIterator
知道预期的modCount
,将值作为字段记住。 Your iterators 1 and 2 will not get confused, because they will be separate objects with separate fields with separate values, which means they will expect different modCount
s.您的迭代器 1 和 2 不会混淆,因为它们将是具有单独字段和单独值的单独对象,这意味着它们将期望不同的
modCount
s。 Further, note that ConcurrentModificationException
s are thrown by "polling", not by "notification".此外,请注意
ConcurrentModificationException
是由“轮询”引发的,而不是由“通知”引发的。 The collection does not need to keep track of its iterators and notify them about modification when you call a method on the collection.集合不需要跟踪其迭代器并在您调用集合上的方法时通知它们有关修改。 Rather, each iterator checks whether the collection has been modified when you call a method on the iterator.
相反,当您在迭代器上调用方法时,每个迭代器都会检查集合是否已被修改。 If you never use an iterator after the collection has been modified, it will never get the chance to throw an exception, so, in your example, no exception will be thrown, and that is the correct behavior.
如果您在修改集合后从不使用迭代器,它将永远不会有机会引发异常,因此,在您的示例中,不会引发异常,这是正确的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.