![](/img/trans.png)
[英]STL-like Java Red-black tree / TreeSet/Map and linked lists with non fail-fast/safe iterators
[英]What are fail-safe & fail-fast Iterators in Java
Java 中有兩種類型的迭代器:fail-safe 和 fail-fast。
這是什么意思,它們之間有什么區別?
它們之間有什么區別...
“故障安全”(在工程中)意味着某些故障不會造成損壞或造成最小損壞。 嚴格來說,Java 中沒有故障安全迭代器這樣的東西。 如果迭代器失敗(在正常意義上的“失敗”),您可以預期會發生損壞。
我懷疑您實際上是指“弱一致性”迭代器。 javadoc 說:
“大多數並發集合實現(包括大多數隊列)也不同於通常的 java.util 約定,因為它們的迭代器和拆分器提供弱一致性而不是快速失敗遍歷。”
通常,弱一致性意味着如果集合在迭代的同時被修改,則迭代所看到的內容的保證較弱。 (詳細信息將在每個並發集合類 javadocs 中指定。)
“Fail-fast”(在系統設計中)意味着積極檢查故障情況,以便在造成過多損壞之前檢測到故障情況(如果可能1 )。 在 Java 中,快速失敗的迭代器通過拋出ConcurrentModificationException
失敗。
“快速失敗”和“弱一致性”的替代方案是語義,其中迭代失敗不可預測; 例如,有時會給出錯誤的答案或拋出意外的異常。 (這是 Java 早期版本中Enumeration
API 的一些標准實現的行為。)
...它們與我們用於收集的迭代器不同嗎?
不。這些是由標准集合類型實現的迭代器的屬性; 即它們要么是“快速失敗”,要么是“弱一致性”......當正確使用同步和 Java 內存模型1 時。
快速失敗迭代器通常使用集合對象上的volatile
計數器來實現。
Iterator
,計數器的當前值嵌入在Iterator
對象中。Iterator
操作時,該方法比較兩個計數器值,如果它們不同,則拋出 CME。相比之下,弱一致性迭代器通常是輕量級的,並且利用了每個並發集合的內部數據結構的特性。 沒有通用的模式。 如果您有興趣,請閱讀不同集合類的源代碼。
1 - 騎手是快速失敗行為假設應用程序 id 在同步和內存模型方面是正確的。 這意味着(例如)如果在沒有適當同步的情況下迭代ArrayList
,結果可能是損壞的列表結果。 “快速失敗”機制可能會檢測到並發修改(盡管不能保證),但它不會檢測到潛在的損壞。 例如, Vector.iterator()
javadoc是Vector.iterator()
說的:
“無法保證迭代器的快速失敗行為,因為一般來說,在存在未同步的並發修改的情況下不可能做出任何硬保證。快速失敗的迭代器在盡力而為的基礎上拋出
ConcurrentModificationException
。因此,它會編寫一個依賴這個異常來保證其正確性的程序是錯誤的:迭代器的快速失敗行為應該只用於檢測錯誤。”
它們是相當快速且弱一致的類型:
如果在迭代時集合的方法(添加/刪除)修改了集合,則java.util
包中的迭代器會拋出ConcurrentModificationException
java.util.concurrent
包中的迭代器通常迭代快照並允許並發修改,但在創建迭代器后可能不會反映集合更新。
唯一的區別是故障安全迭代器不會拋出任何異常,這與故障快速迭代器相反。
如果在一個線程迭代它時在結構上修改了 Collection。 這是因為它們處理的是 Collection 的克隆而不是原始集合,這就是它們被稱為故障安全迭代器的原因。
CopyOnWriteArrayList 的迭代器是故障安全迭代器的一個例子,由 ConcurrentHashMap keySet 編寫的迭代器也是故障安全迭代器,在 Java 中從不拋出 ConcurrentModificationException。
此場景與“並發處理”相關,意味着有多個用戶訪問同一資源。 在這種情況下,其中一個用戶嘗試修改導致“ConcurrentProcessingException”的資源,因為在這種情況下其他用戶獲得了不正確的數據。 這兩種類型都與這種情況有關。
簡單來說,
快速失敗:
故障安全:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.