Java 集合遍歷過程中修改數據觸發 Fail-Fast 機制 ,導致報ConcurrentModificationException異常

Java Fail-Fast 機制

Fail-Fast 機制是 Java 集合框架中的一種錯誤檢測機制,用于在遍歷集合時檢測結構修改。如果在迭代器創建之后,集合被修改(例如添加或刪除元素),并且這種修改不是通過迭代器自身的 remove() 方法進行的,那么迭代器會立即拋出 ConcurrentModificationException 異常,以防止不一致或不可預測的行為。

工作原理
  1. 修改計數器

    • 集合類(如 ArrayListHashMap 等)內部維護一個 modCount 計數器,記錄集合被結構性修改的次數(結構性修改包括添加或刪除元素,但不包括通過迭代器自身的 remove() 方法進行的刪除)。
  2. 迭代器的預期修改計數

    • 當創建迭代器時,迭代器會記錄當前集合的 modCount 值,作為其 expectedModCount
    • 在每次調用迭代器的 next() 方法時,迭代器會檢查 expectedModCount 是否與集合的當前 modCount 一致。
  3. 檢測不一致

    • 如果在迭代過程中,集合的 modCount 發生變化(即 expectedModCount 不等于 modCount),迭代器會立即拋出 ConcurrentModificationException 異常。
示例代碼
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class FailFastExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);// 在迭代過程中修改集合,會拋出 ConcurrentModificationExceptionlist.add("D");}}
}

輸出

A
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)at java.util.ArrayList$Itr.next(ArrayList.java:859)at FailFastExample.main(FailFastExample.java:13)
解決方法
  1. 使用迭代器自身的 remove() 方法

    • 如果需要在遍歷過程中刪除元素,應使用迭代器的 remove() 方法,而不是直接操作集合。
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {String element = iterator.next();if (element.equals("B")) {iterator.remove(); // 安全刪除元素}
    }
    
  2. 使用線程安全的集合類

    • 使用 java.util.concurrent 包中的線程安全集合類,如 CopyOnWriteArrayListConcurrentHashMap 等。
    import java.util.concurrent.CopyOnWriteArrayList;public class ConcurrentExample {public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();list.add("A");list.add("B");list.add("C");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);// 在迭代過程中修改集合,不會拋出 ConcurrentModificationExceptionlist.add("D");}}
    }
    
  3. 使用 Collections.synchronizedList()Collections.synchronizedSet()

    • 將集合包裝為線程安全的集合。
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;public class SynchronizedExample {public static void main(String[] args) {List<String> list = Collections.synchronizedList(new ArrayList<>());list.add("A");list.add("B");list.add("C");synchronized (list) {Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);// 在迭代過程中修改集合,不會拋出 ConcurrentModificationExceptionlist.add("D");}}}
    }
    
注意事項
  1. 單線程環境

    • 在單線程環境中,Fail-Fast 機制有助于及時發現集合被意外修改的問題。
    • 但需要注意在迭代過程中不要直接修改集合,除非使用迭代器自身的 remove() 方法。
  2. 多線程環境

    • Fail-Fast 機制在多線程環境中可能會導致 ConcurrentModificationException 異常。
    • 應使用線程安全的集合類或同步機制來避免此類問題。
  3. 性能影響

    • Fail-Fast 機制本身對性能的影響較小,主要體現在每次迭代時的 modCount 檢查。
    • 但在多線程環境下,頻繁的同步操作可能會顯著影響性能。
總結
  • Fail-Fast 機制 是 Java 集合框架中用于檢測集合在迭代過程中被修改的一種機制。
  • 通過在迭代過程中拋出 ConcurrentModificationException 異常,Fail-Fast 機制可以及時發現不一致的行為,確保集合的完整性和一致性。
  • 在使用 Fail-Fast 機制時,需要注意在迭代過程中不要直接修改集合,除非使用迭代器自身的 remove() 方法。
  • 對于多線程環境,建議使用線程安全的集合類或同步機制來避免 ConcurrentModificationException 異常。

通過合理使用 Fail-Fast 機制,可以提高代碼的健壯性和可靠性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73413.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73413.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73413.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt-ZMQ的使用補充(pub-sub)

之前寫過一篇Qt使用ZMQ的博客Qt網絡編程-ZMQ的使用&#xff0c;本文是其的補充部分。 Linux上編譯使用 首先這次實在Linux上進行演示&#xff0c;下載zmq源碼&#xff0c;安裝cmake&#xff0c;使用cmake進行編譯。下載之后解壓&#xff1a; 輸入命令&#xff1a; cd ..mkdi…

C++的名稱空間

C++的名稱空間(namespace)是一種用于組織代碼、防止命名沖突的機制。以下是名稱空間的詳細說明和使用建議: 1. 名稱空間的定義 使用namespace關鍵字定義,內部可包含變量、函數、類等: namespace MyNamespace {int a;void func() {} }2. 訪問方式 作用域解析運算符:::顯…

記錄致遠OA服務器硬盤升級過程

前言 日常使用中OA系統突然卡死&#xff0c;刷新訪問進不去系統&#xff0c;ping服務器地址正常&#xff0c;立馬登錄服務器檢查&#xff0c;一看磁盤爆了。 我大腦直接萎縮了&#xff0c;誰家OA系統配400G的空間啊&#xff0c;過我手的服務器沒有50也是30臺&#xff0c;還是…

[測試]自動化的概念 及使用Selenium實現Web自動化測試

文章目錄 1. 自動化1.1 自動化概念1.2 自動化分類1.2.1 接口自動化1.2.2 UI自動化 1.3 自動化測試金字塔 2. Web自動化測試2.1 驅動 3. Selenium3.1 一個簡單的Web自動化示例3.2 Selenium 驅動 瀏覽器的工作原理 1. 自動化 1.1 自動化概念 自動化是指自動地代替人的行為完成…

Python教程(三):類對象、閉包、裝飾器、類型注解、MRO

Python總結&#xff08;三&#xff09; 本系列其他教程&#xff1a; Python教程(一)&#xff1a;基本語法、流程控制、數據容器 Python教程(二)&#xff1a;函數、異常、模塊&包、文件讀取、常用模塊 文章目錄 Python總結&#xff08;三&#xff09;一、類&對象1.1 成…

什么是 HTML?

HTML 是用來描述網頁的一種語言。 HTML 指的是超文本標記語言: HyperText Markup LanguageHTML 不是一種編程語言&#xff0c;而是一種標記語言標記語言是一套標記標簽 (markup tag)HTML 使用標記標簽來描述網頁HTML 文檔包含了HTML 標簽及文本內容HTML文檔也叫做 web 頁面 HT…

【Hadoop】Hadoop的簡要介紹

Hadoop是一個由Apache基金會所開發的分布式系統基礎架構&#xff0c;主要用于解決海量數據的存儲及分析計算問題。以下是對Hadoop的詳細介紹&#xff1a; 目錄 一、Hadoop的起源與發展 二、Hadoop的核心組件 1.HDFS&#xff1a; 2.MapReduce&#xff1a; 3.YARN&#xff…

如何用AI制作PPT,輕松實現高效演示

如何用AI制作PPT&#xff0c;輕松實現高效演示&#xff01;在今天這個快節奏的時代&#xff0c;我們的工作方式越來越依賴智能工具。而當涉及到演示文稿時&#xff0c;傳統的PPT制作方式往往繁瑣且耗時。很多人一提到制作PPT就頭大&#xff0c;特別是在內容需要多次修改、調整布…

Canoe Panel基礎功能介紹

文章目錄 一、新建 Panel 面板二、添加 Panel 面板三、刪除 Panel 面板四、Panel視圖&#xff08;views&#xff09;五、控件布局1. 對齊布局2. 控件大小布局 六、Panel 屬性設置1. 設置背景色和背景圖片2. 調整 Panel 畫布大小 提示&#xff1a;如何使用 Panel 面板參考 CANoe…

超聲重建,3D重建 超聲三維重建,三維可視化平臺 UR 3D Reconstruction

1. 超聲波3D重建技術的實現方法與算法 技術概述 3D超聲重建是一種基于2D超聲圖像生成3D體積數據的技術&#xff0c;廣泛應用于醫學影像領域。通過重建和可視化三維結構&#xff0c;3D超聲能夠顯著提高診斷精度和效率&#xff0c;同時減少醫生的腦力負擔。本技術文檔將詳細闡述…

2.2 企業級ESLint/Prettier規則定制

文章目錄 1. 為什么需要企業級代碼規范2. 工具選型對比3. 完整配置流程3.1 項目初始化3.2 ESLint深度配置3.3 Prettier精細配置3.4 解決規則沖突4. 高級定制方案4.1 自定義ESLint規則4.2 擴展Prettier插件5. 團隊協作策略5.1 配置共享方案5.2 版本控制策略6. CI/CD集成7. 常見問…

QT創建項目(項目模板、構建系統、選擇類、構建套件)

1. 項目模版 項目類型界面技術適用場景核心依賴模塊開發語言Qt Widget ApplicationC Widgets傳統桌面應用&#xff08;復雜控件&#xff09;Qt WidgetsCQt Console Application無 GUI命令行工具、服務Qt CoreCQt Quick ApplicationQML/Quick現代跨平臺應用&#xff08;動畫/觸…

oracle11.2.0.4 RAC 保姆級靜默安裝(二) DB數據庫軟件

1.響應文件配置 [rootdb11g1 software]# su - oracle [oracledb11g1 ~]$ cd /software/database/ [oracledb11g1 database]$ cd response/ [oracledb11g1 response]$ vi db_install.rsp oracle.install.optionINSTALL_DB_SWONLY ORACLE_HOSTNAMEdb11g1 UNIX_GROUP_NAME…

日語學習-日語知識點小記-構建基礎-JLPT-N4N5階段(22):給與和得到相關用法

日語學習-日語知識點小記-構建基礎-JLPT-N4&N5階段(22):給與和得到相關用法 1、前言(1)情況說明(2)工程師的信仰2、知識點(1) あげます :給(2)もらいます(いただきます) 得到。(3) くれました :主要是給我。3、單詞(1)日語單詞(2)日語片假名…

Qt5中視口(ViewPort)與窗口(Window)

在Qt中&#xff0c;setViewport和setWindow是用于控制坐標系映射的核心方法&#xff0c;二者共同決定了繪圖邏輯與物理設備之間的轉換關系。以下是關鍵點總結&#xff1a; ?1. 視口&#xff08;Viewport&#xff09;與窗口&#xff08;Window&#xff09;的核心區別? ?視口…

迪威 3D 模型發布系統:制造業產品展示革新利器

在競爭激烈的制造業領域&#xff0c;如何將產品全方位、直觀地呈現給客戶&#xff0c;成為企業脫穎而出的關鍵。傳統的產品展示方式往往受限于平面資料或有限的實物展示&#xff0c;難以讓客戶深入了解產品的復雜結構與精妙細節。迪威 3D 模型發布系統的問世&#xff0c;為制造…

EasyCVR安防視頻匯聚平臺助力工業園區構建“感、存、知、用”一體化智能監管體系

在現代工業園區的安全管理和高效運營中&#xff0c;視頻監控系統扮演著不可或缺的角色。然而&#xff0c;隨著園區規模的擴大和業務的復雜化&#xff0c;傳統的視頻監控系統面臨著諸多挑戰&#xff0c;如設備眾多難以統一管理、數據存儲分散、智能分析能力不足、信息利用率低下…

解決 Redis 后臺持久化失敗的問題:內存不足導致 fork 失敗

文章目錄 解決 Redis 后臺持久化失敗的問題&#xff1a;內存不足導致 fork 失敗問題背景與成因解決方案修改內核參數 vm.overcommit_memory增加系統內存或 Swap 空間調整 Redis 配置 stop-writes-on-bgsave-error 在 Docker 環境中的注意事項總結 解決 Redis 后臺持久化失敗的問…

反射、反射調用以及修改成員變量,成員方法,構造函數、反射的應用

DAY11.2 Java核心基礎 反射&#xff08;第二彈&#xff09; 第一彈請訪問鏈接&#xff1a; 反射&#xff08;第一篇&#xff09; getMethod(String name, Class… parameterTypes)getMethods()getDeclaredMethod(String name,Class… parameterTypes)getDeclaredMethods() …

【鴻蒙開發】Hi3861學習筆記- 外部中斷

00. 目錄 文章目錄 00. 目錄01. 概述02. EXTI相關API03. 硬件設計04. 軟件設計05. 實驗現象06. 附錄 01. 概述 我們在做按鍵控制實驗時&#xff0c;雖然能實現 IO 口輸入功能&#xff0c;但代碼是一直在檢測 IO 輸入口的變化&#xff0c;因此效率不高&#xff0c;特別是在一些…