for循環中list觸發fast-fail或不觸發的原理和方法

Iterable和Iterator

在這里插入圖片描述
Iterator接口位于的位置是java.util.Iterator,它主要有兩個抽象方法供子類實現。hasNext()用來判斷還有沒有數據可供訪問,next()用來訪問下一個數據。

集合Collection不是直接去實現Iterator接口,而是去實現Iterable接口。在這里插入圖片描述
用這個Iterable接口的iterator()方法返回當前集合迭代器。
集合Collection體系的集合都得按照使用iterator()的方式返回可供遍歷的迭代器iterator
在這里插入圖片描述
集合使用Iterable接口的iterator()方法返回迭代器Iterator有很多好處。
在這里插入圖片描述
比如有兩個線程都需要使用迭代器進行遍歷集合的操作,如果通過直接實現Iterator接口來拿迭代器。首先兩者拿的是同一個迭代器,并且兩者不同步,一個都遍歷結束了,另一個都還沒開始就無法遍歷集合了,但是他本來循環從頭開始遍歷集合的所有數據的。

如果使用Iterable接口的iterator()方法返回迭代器Iterator,那兩者獲得的就是不同迭代器了,就互不影響,自己可以按照自己的進度遍歷集合就行。
在這里插入圖片描述


for-each就是迭代器的語法糖
要使用增強型 for 循環(也稱為 for-each 循環)遍歷一個集合,集合的類需要實現 java.lang.Iterable 接口。Iterable 接口定義了一個方法 iterator(),它返回一個 Iterator 對象,用于遍歷集合的元素。

import java.util.Iterator;
import java.util.NoSuchElementException;// Iterable位于java.lang包下,不用顯式import
public class MyCollection<T> implements Iterable<T> {private T[] elements;private int size;@SuppressWarnings("unchecked")public MyCollection(int capacity) {elements = (T[]) new Object[capacity];size = 0;}public void add(T element) {if (size < elements.length) {elements[size++] = element;} else {throw new IllegalStateException("Collection is full");}}// 當一個類要實現 Iterable 接口,它必須提供一個 iterator() 方法,該方法返回一個 Iterator 對象。@Overridepublic Iterator<T> iterator() {return new MyIterator();}private class MyIterator implements Iterator<T> {private int currentIndex = 0;@Overridepublic boolean hasNext() {return currentIndex < size;}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}return elements[currentIndex++];}}
}
MyCollection<String> collection = new MyCollection<>(10);collection.add("a");collection.add("b");collection.add("c");// 使用增強型 for 循環for (String element : collection) {System.out.println(element);}// 和增強for循環等價的顯式迭代器循環// 當一個類實現了 Iterable 接口,它必須提供一個 iterator() 方法,該方法返回一個 Iterator 對象。// 這個 Iterator 對象實現了 hasNext() 和 next() 方法,用于遍歷集合中的元素。// 下面的 iterator 是通過集合類實現的 Iterable 接口的 iterator() 方法獲得的Iterator<String> iterator = collection.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);

快速失敗機制的工作原理

fail-fast 機制是java集合(Collection)中的一種錯誤機制。當多個線程對同一個集合的內容進行操作時,就可能會產生fail-fast事件
Java中的集合類(如ArrayList、LinkedList、HashMap等)使用快速失敗機制來檢測在迭代過程中對集合的結構性修改。
工作原理如下:

  1. modCount:每個集合類都有一個modCount字段,用于記錄集合結構性修改的次數。結構性修改是指添加或刪除元素,改變集合的大小。
  2. 迭代器的expectedModCount:當創建迭代器時,迭代器會保存當前集合的modCount值到一個名為expectedModCount的字段中。
  3. 一致性檢查:在每次調用迭代器的next()hasNext()方法時,迭代器首先會檢查modCount是否與expectedModCount相同。如果不相同,說明集合在迭代過程中的結構被修改過,迭代器會拋出ConcurrentModificationException

總的來說:只要是涉及了改變ArrayList元素的個數的方法都會導致modCount的改變。當多線程環境下,由于expectedModCount與modCount的改變不同步,導致兩者之間不等,從而產生fast-fail。

在這里插入圖片描述
這里的拋出異常,停止執行就是fail-fast,就是當自己遇到無法處理的情況時的處理方式。

下面是ConcurrentModificationException異常的例子:

List<String> list = new ArrayList<>();
list.add("a");
Iterator<String> iterator = list.iterator();  // expectedModCount = modCount = 0
list.add("b");  // modCount = 1
iterator.next(); // expectedModCount != modCount, 拋出ConcurrentModificationException異常

for-each循環對集合進行增刪也可能拋出異常,因為for-each在反編譯下可以發現就是迭代器的語法糖,所以涉及到對迭代器的使用。

		List<String> collection = new ArrayList<>();collection.add("a");collection.add("b");// 使用增強型 for 循環for (String element : collection) {System.out.println(element);}// 和增強for循環等價的顯式迭代器循環// 當一個類實現了 Iterable 接口,它必須提供一個 iterator() 方法,該方法返回一個 Iterator 對象。// 這個 Iterator 對象實現了 hasNext() 和 next() 方法,用于遍歷集合中的元素。// 下面的 iterator 是通過集合類實現的 Iterable 接口的 iterator() 方法獲得的Iterator<String> iterator = collection.iterator();while (iterator.hasNext()) {String element = iterator.next();if ("a".equals(element)) {collection.remove(element);}}

想要在循環時進行增刪操作,也就是進行這類對集合結構性有影響的操作,就要保證數據隔離性,下面是三種數據隔離性的處理方式,本質都是復制東西,只是復制的東西有所不同。
在這里插入圖片描述
寫入時復制(copy-on-write, 簡稱COW)。
在這里插入圖片描述

在這里插入圖片描述
GC 代表 “Garbage Collection”(垃圾回收)。COW讀操作時并沒有加鎖,這是為了提高讀操作的性能,但是有缺點,比如讀數據的時候可能讀不到最新的數據。例如,線程1往集合里面add數據才增加了一半,線程2這時候就去讀數據,那讀到的就還是老數據。

在這里插入圖片描述
這樣的話就只有增刪才需要開辟一個新數組,其他情況都是使用原數組引用來讀取原數組。

// 可以像使用普通的 ArrayList 一樣使用 CopyOnWriteArrayList(寫入時復制),并且可以通過 List 接口來引用它List<String> cowList = new CopyOnWriteArrayList<>();cowList.add("a");cowList.add("b");cowList.add("c");Iterator<String> iterator = cowList.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}cowList.remove("b");Iterator<String> iterator2 = cowList.iterator();while (iterator2.hasNext()) {System.out.println(iterator2.next());}

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

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

相關文章

【Python】字典練習

python期考練習 目錄 1. 首都名?編輯 2. 摩斯電碼 3. 登錄 4. 學生的姓名和年齡?編輯 5. 電商 6. 學生基本信息 7. 字母數 1. 首都名 初始字典 (可復制) : d{"China":"Beijing","America":"Washington","Norway":…

HCM智能人力資源系統存在命令執行漏洞Getshell

0x01 閱讀須知 技術文章僅供參考&#xff0c;此文所提供的信息只為網絡安全人員對自己所負責的網站、服務器等&#xff08;包括但不限于&#xff09;進行檢測或維護參考&#xff0c;未經授權請勿利用文章中的技術資料對任何計算機系統進行入侵操作。利用此文所提供的信息而造成…

防爆對講終端是什么?在哪些行業中應用廣泛?

防爆對講終端是一種特殊設計的通信設備&#xff0c;它具備防爆性能和可靠的通信功能&#xff0c;確保在存在爆炸性氣體或粉塵的危險環境中使用時不會引發爆炸或火災等危險情況。這種設備通過特殊的設計和防護措施&#xff0c;如采用防爆材料、防靜電、絕緣、阻燃材料等&#xf…

ABAQUS軟件天津正版代理商億達四方:創新技術,驅動產業升級

在環渤海經濟圈的核心地帶——天津&#xff0c;隨著智能制造與高新技術產業的蓬勃發展&#xff0c;對高端仿真軟件的需求日益增長。億達四方&#xff0c;作為ABAQUS在天津的官方正版代理商&#xff0c;憑借其深厚的行業經驗和卓越的服務體系&#xff0c;正為這片熱土上的科研機…

2024年度濰坊市職業技能大賽——網絡搭建(網絡與信息安全管理員)職業技能競賽樣題

2024年度濰坊市職業技能大賽 ——網絡搭建&#xff08;網絡與信息安全管理員&#xff09;職業技能競賽樣題 網絡搭建職業技能競賽組委會 2024年6月 一、項目簡介 &#xff08;一&#xff09;競賽須知 1.技能操作比賽時間150分鐘&#xff0c;你需要合理分配時間。 2.如果沒…

Hive常用的內置函數

文章目錄 聚合類1.指定列值的數目2.指定列值求和3.最大值4.最小值5.平均值6.中位數函數7.分位數函數 數值類1.取整函數Round(a)2.指定精度取整ROUND(double a,int b)3.向上取整FLOOR()4.向下取整CEIL()5.隨機數 rand()6.絕對值函數 日期類獲取當前日期獲取當前時間戳日期前后日…

C++:枚舉類的使用案例及場景

一、使用案例 在C中&#xff0c;枚舉類&#xff08;也稱為枚舉類型或enum class&#xff09;是C11及以后版本中引入的一種更加強大的枚舉類型。與傳統的枚舉&#xff08;enum&#xff09;相比&#xff0c;枚舉類提供了更好的類型安全性和作用域控制。下面是一個使用枚舉類的案…

(linux系統服務)Linux下yum源配置實戰

一、Linux下軟件包的管理 1、軟件安裝方式 ① RPM包管理&#xff08;需要單獨解決依賴問題&#xff09; ② YUM包管理&#xff08;需要有網絡及YUM倉庫的支持&#xff0c;會自動從互聯網下載軟件&#xff0c;自動解決依賴&#xff09; ③ 源碼安裝&#xff08;安裝過程比較…

總體設計在軟件設計中的意義

總體設計&#xff08;High-Level Design, HLD&#xff09;是軟件開發生命周期中的一個關鍵階段&#xff0c;旨在從宏觀層面定義系統的結構和主要組件。總體設計的目標是為詳細設計和實現提供一個清晰的框架和藍圖。 總體設計的意義 明確系統架構&#xff1a;總體設計幫助開發…

基于Java的外賣點餐系統設計與實現

作者介紹&#xff1a;計算機專業研究生&#xff0c;現企業打工人&#xff0c;從事Java全棧開發 主要內容&#xff1a;技術學習筆記、Java實戰項目、項目問題解決記錄、AI、簡歷模板、簡歷指導、技術交流、論文交流&#xff08;SCI論文兩篇&#xff09; 上點關注下點贊 生活越過…

深?理解 JVM 底層原理、垃圾回收機制,能通過mat、jstat進行JVM參數調優

深入理解JVM&#xff08;Java虛擬機&#xff09;底層原理和垃圾回收機制是Java開發者和系統管理員的重要技能&#xff0c;尤其是在性能調優方面。下面是一些關鍵點&#xff0c;幫助你更好地理解這些概念&#xff1a; ### JVM 底層原理 1. **類加載機制**&#xff1a;JVM如何加…

java+mysql教師管理系統

完整源碼地址 教師信息管理系統使用命令行交互的方式及數據庫連接實現教師信息管理系統&#xff0c;該系統旨在實現教師信息的管理&#xff0c;并根據需要進行教師信息展示。該軟件的功能有如下功能 (1)基本信息管理(教師號、姓名、性別、出生年月、職稱、學歷、學位、教師類型…

25西安電子科技大學研究生政策(最新)

25西安電子科技大學研究生政策&#xff08;最新&#xff09; 01全國研究生報名情況 全國研究生報名人數438萬&#xff0c;首次下降超36萬人。 02西電研究生全日制/非全日制報名情況 西電碩士研究生報考錄取情況&#xff08;包含全日制、非全日制&#xff09;&#xff0c;2024年…

python-數據容器對比總結

基于各類數據容器的特點&#xff0c;它們的應用場景如下&#xff1a; 數據容器的通用操作 - 遍歷 數據容器的通用統計功能 容器的通用轉換功能 容器通用排序功能 容器通用功能總覽

C-特性和新特性

C特性和新特性 C11 C11是C編程語言的一個重要標準版本&#xff0c;是C98標準發布后13年來的第一次重大修正&#xff0c;它引入了許多新特性和改進&#xff0c;極大地增強了C語言的表達能力和開發效率。 C11是C編程語言的一個重要標準版本&#xff0c;由國際標準化組織(ISO)和…

如何在Java中實現自定義數據結構:從頭開始

如何在Java中實現自定義數據結構&#xff1a;從頭開始 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何在Java中實現自定義數據結構&#xff…

一文徹底搞懂Transformer - Input(輸入)

一、輸入嵌入&#xff08;Input Embedding&#xff09; 詞嵌入&#xff08;Word Embedding&#xff09;&#xff1a;詞嵌入是最基本的嵌入形式&#xff0c;它將詞匯表中的每個單詞映射到一個固定大小的向量上。這個向量通常是通過訓練得到的&#xff0c;能夠捕捉單詞之間的語義…

HTTP入門

入門HTTP協議 1. 原理介紹 爬蟲就是用程序模擬瀏覽器的行為&#xff0c;發送請求給服務器&#xff0c;獲取網頁的內容&#xff0c;解析網頁數據。 要學會爬蟲&#xff0c;先要了解瀏覽器是如何和服務器交流的。瀏覽器通過HTTP協議和服務器交流。 2. HTTP協議簡介 2.1…

第4篇 區塊鏈的優勢與挑戰:為什么區塊鏈如此重要?

區塊鏈聽起來像是一種高科技的魔法&#xff0c;很多人都想知道它到底是怎么回事&#xff0c;為什么會引起如此大的關注。今天&#xff0c;我們就來揭開區塊鏈的神秘面紗&#xff0c;看看它的優勢和挑戰&#xff0c;順便聊聊為什么它會變得如此重要。 優勢篇 1. 去中心化&…

【pg】去除pg數據庫字段值中的空格

如何批量去除PostgreSQL數據庫字段值中的空格 在處理數據庫中的數據時&#xff0c;經常會遇到字段值末尾帶有多余空格的問題。這些空格可能是用戶輸入錯誤或數據遷移過程中引入的&#xff0c;可能會影響數據的準確性和一致性。本文將介紹如何使用 PostgreSQL 的 SQL 語句批量去…