2012-01-05 26 views

回答

12

快速失敗意味着,如果在迭代通過它時嘗試修改內容,它將失敗並拋出ConcurrentModificationException。

Set keys = hashMap.keySet(); 
for (Object key : keys) { 
    hashMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here 
} 

對於哈希表枚舉:

Enumeration keys = hashTable.keys(); 
while (keys.hasMoreElements()) { 
      hashTable.put(someKey, someValue); //this is ok 
    } 
+3

Hastable的迭代器是快速失敗的。它的枚舉不是。 – 2012-01-05 23:00:45

+0

你是對的!謝謝! – evanwong 2012-01-05 23:05:11

3

當調用iterator.next()時,如果在創建迭代器的時刻和調用next()時刻之間進行了任何修改,立即拋出ConcurrentModificationException。這就是快速失敗的意思。

Hashtable返回的枚舉不具有此行爲。他們假設你知道你在做什麼,如果你修改地圖而使用其枚舉迭代地圖,他們的行爲AFAIK是未定義的。

3

最好的方法是可能查看由每個類的Open JDK實現實現的每個類的源代碼;這樣,你可以直接從馬的嘴裏得到你的答案,因爲它是:-)

除此之外,從這個意義上講,「fail-fast」意味着如果一個HashMap上的Iterator會拋出一個異常檢測到另一個線程已經修改了目標HashMap - 如果您查看HashMap的源代碼,您會看到這是通過簡單地檢查一個計數器以獲得預期修改的數量來完成的。如果修改計數與預期的迭代器不同,這意味着自上次檢查後有人進入並與HashMap混淆,因此迭代器會拋出ConcurrentModificationException

一個「非故障快速」迭代器不會費心去檢查,並且愉快地繼續它在底層數據結構中的業務。因此,您可以獲得一些靈活性(在這種情況下可能存在可疑的靈活性),以換取稍後可能遇到的錯誤;即嘗試訪問不再存在的值。

與所有fail-fast策略一樣,這個想法是,越早檢測到錯誤,恢復或調試就越容易。

+3

不只是另一個線程。如果在遍歷迭代時修改映射,即使在同一個線程中,也會拋出ConcurrentModification(除非使用迭代器本身來修改映射) – 2012-01-05 22:59:08

+0

非常真實!我自己做的一個有時候令人困惑的錯誤:-) – 2012-01-05 23:01:08

相關問題