Java Colllection的迭代器兩種失敗模式的優缺點

banq發表於2021-08-26

Java 中的迭代器iterators是一種幫助開發人員避免執行時異常的簡單機制。讓我們探索快速失敗和安全失敗迭代器之間的區別。
Java 中的迭代器通常期望對它們迴圈遍歷的資料結構進行獨佔訪問。如果另一個執行緒在迭代器處理物件時嘗試修改物件集合,則會丟擲 ConcurrentModificationException。由於與管理任意排程的執行緒相關的複雜性,對 ConcurrentModificationException 進行故障排除可能很困難。幸運的是,Java 提供了一種簡單的機制來幫助開發人員避免這種異常。
 

兩種失敗模式
Java 迭代器分為兩個獨立的陣營失敗模式:fail-fast 和fail-safe:
fail-fast快速失敗是引發 ConcurrentModificationException 的原因;而fail-safe故障安全的迭代器不會丟擲這個異常。當然,決定使用fail-safe故障安全迭代器需要更多的考慮,而不僅僅是避免執行時異常的願望。
ArrayList 和 HashMap 類具有fail-fast快速失敗的迭代器;CopyOnWriteArrayList 和 ConcurrentHashMap 類使用fail-safe故障安全迭代器。
 

故障安全迭代器的好處
當感興趣的集合發生結構變化時,故障安全迭代器不會丟擲異常,因為它們與克隆一起工作,而不是集合本身。因此,故障安全迭代器會忽略底層集合發生的更改。
故障安全迭代器提供的主要好處是它們最大限度地減少了丟擲異常的可能性。但這種好處是有代價的,其中之一是增加了記憶體需求。任何時候JVM克隆物件時,都需要額外的記憶體空間。對於大型集合,記憶體佔用量可能很大。
 

故障安全迭代器的缺點
如果 JVM 分配和釋放越來越多的記憶體,垃圾收集例程將不得不更頻繁地執行。這將增加 CPU 負載,觸發 stop-the-world 事件並降低整體應用程式效能。
另一個缺點是它提供的結果可能與底層集合不同步。畢竟,克隆不會反映在進行克隆後底層集合發生的任何更改。如果您的應用程式不能接受這種不一致,則不應使用故障安全迭代器。
  

兩者比較
如果目標是避免異常,系統資源充足,並且在迭代器執行時對底層集合類的更新不會對應用程式的業務需求產生負面影響,那麼故障安全迭代器是一個明智的選擇。否則,堅持使用快速失敗的迭代器。

 

相關文章