簡體   English   中英

Java迭代器如何檢測集合被修改拋出ConcurrentModificationException?

[英]How Java iterators detect the collection is modified to throw ConcurrentModificationException?

Java 迭代器如何檢測集合被修改? 試圖搜索,發現:

通常 java.util package 中的傳統集合類使用一個 int 變量 (modCount) 來跟蹤修改(添加和刪除)。

當我們從這些集合類中請求 Iterator 時,返回的 Iterator 的 object 將提供現有的修改計數變量作為其預期的修改計數。

在調用 next() 方法時,迭代器 object 會根據預期的修改計數值檢查當前修改計數變量值。

在不匹配的情況下,它會通過拋出 java.util package 中存在的 ConcurrentModificationException 快速失敗,這是一個 RuntimeException。

但是如果我們

  1. 修改前推遲迭代器
  2. 修改集合
  3. 修改發生后創建第二個迭代器並迭代

?

使用第二個迭代器似乎一切正常,不是嗎? 那么 modCount 呢? 修改后的集合應該通知第一個迭代器拋出異常,同時不應該通知第二個。 請解釋一下 modCount 是如何工作的? 對 modCount 的行為進行編程或為每個迭代器保留 modCounts 的集合應該是一個挑戰。 無論如何,請澄清多個迭代器如何同時獨立地驗證它們的一致性?

一般來說,它是這樣工作的:

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

每個MyIterator知道預期的modCount ,將值作為字段記住。 您的迭代器 1 和 2 不會混淆,因為它們將是具有單獨字段和單獨值的單獨對象,這意味着它們將期望不同的modCount s。 此外,請注意ConcurrentModificationException是由“輪詢”引發的,而不是由“通知”引發的。 集合不需要跟蹤其迭代器並在您調用集合上的方法時通知它們有關修改。 相反,當您在迭代器上調用方法時,每個迭代器都會檢查集合是否已被修改。 如果您在修改集合后從不使用迭代器,它將永遠不會有機會引發異常,因此,在您的示例中,不會引發異常,這是正確的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM