for循环中list触发fast-fail或不触发的原理和方法

news2025/1/12 12:04:17

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 对象。
    @Override
    public Iterator<T> iterator() {
        return new MyIterator();
    }

    private class MyIterator implements Iterator<T> {
        private int currentIndex = 0;

        @Override
        public boolean hasNext() {
            return currentIndex < size;
        }

        @Override
        public 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.coloradmin.cn/o/1888886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion web UI 插件

2024.7.3更新&#xff0c;持续更新中 如果需要在linux上自己安装sd&#xff0c;参考&#xff1a;stable diffusion linux安装 插件复制到 /stable-diffusion-webui/extensions 目录下&#xff0c;然后重新启动sd即可 一、插件安装方法 每种插件的安装方法可能略有不同&#xf…

java内存管理机制(二)-内存分配

在上一篇文章中&#xff0c;我们花了较大的篇幅去介绍了JVM的运行时数据区&#xff0c;并且重点介绍了栈区的结构及作用&#xff0c;在本文中&#xff0c;我们将主要介绍对象的创建过程及在堆中的分配方式。 对象的创建 在上文我们提过一些问题&#xff0c;你的对象是怎么new…

bWAPP靶场安装

bWAPP安装 下载 git地址&#xff1a;https://github.com/raesene/bWAPP 百度网盘地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1Y-LvHxyW7SozGFtHoc9PKA 提取码&#xff1a;4tt8 –来自百度网盘超级会员V5的分享 phpstudy中打开根目录&#xff0c;并将下载的文…

【python】PyQt5事件机制、定时器原理分析和实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

基于LLM(Large Language Model,大语言模型)的智能问答系统

基于LLM&#xff08;Large Language Model&#xff0c;大语言模型&#xff09;的智能问答系统是一种利用先进的人工智能技术&#xff0c;尤其是自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;来构建能够理解和回答用户问题的系统。这种系统通过训练大量文本数据&…

德国Testing Expo丨落幕不散场!知迪展台风采回顾

德国斯图加特国际展览中心&#xff0c;随着全球汽车产业的目光聚焦&#xff0c;Automotive Testing Expo Europe 2024圆满落幕。在这场汇聚了全球顶尖汽车测试技术的盛会中&#xff0c;知迪科技凭借卓越的技术实力和前瞻性的解决方案&#xff0c;成为了现场诸多专业观众的瞩目焦…

pydub、ffmpeg 音频文件声道选择转换、采样率更改

快速查看音频通道数和每个通道能力判断具体哪个通道说话&#xff1b;一般能量大的那个算是说话 import wave from pydub import AudioSegment import numpy as npdef read_wav_file(file_path):with wave.open(file_path, rb) as wav_file:params wav_file.getparams()num_cha…

红酒与舞蹈:舞动的味觉艺术

在艺术的海洋中&#xff0c;红酒与舞蹈总是能激起人们心中较温柔的涟漪。红酒以其深邃的色泽、馥郁的香气&#xff0c;诠释着味觉的艺术&#xff1b;而舞蹈&#xff0c;则以优雅的姿态、灵动的步伐&#xff0c;演绎着视觉的盛宴。当红酒遇上舞蹈&#xff0c;一场别开生面的艺术…

Ubuntu防火墙相关内容

Ubuntu防火墙相关的命令&#xff0c;主要用于日常使用过程中&#xff0c;忘记命令时查找方便&#xff0c;不用再去各种地方搜索了。以下命令均已root用户执行&#xff0c;如果是非root用户&#xff0c;需要添加sudo 查看防火墙的启用状态 ufw status 说明是启用状态。 启用防…

边缘和条件高斯相乘后的高斯分布形式【模式识别书】

边缘和条件高斯相乘后的高斯分布形式【模式识别书】 结论来自&#xff1a;《Pattern Recognition and Machine Learning》公式(2.115)

前端 原型 原型链的理解

概念 原型 对象中固有的 __proto__ 属性&#xff0c;该属性指向对象的 prototype 原型属性。 原型链 当我们访问一个对象的属性时&#xff0c;如果这个对象内部不存在这个属性&#xff0c;那么它就会去它的原型对象 里找这个属性&#xff0c;这个原型对象又会有自己的原…

自然语言处理与Transformer模型:革新语言理解的新时代

引言 自然语言处理&#xff08;NLP&#xff09;是人工智能和计算机科学的一个重要分支&#xff0c;旨在使计算机能够理解、生成和处理人类语言。随着互联网和数字化信息的爆炸性增长&#xff0c;NLP在许多领域中的应用变得越来越重要&#xff0c;包括&#xff1a; 搜索引擎&am…

.NET 漏洞情报 | 某云平台存在SQL注入漏洞

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

Django学习第二天

启动项目命令 python manage.py runserver 动态获取当前时间 javascript实现数据动态更新代码 <script>setInterval(function() {var currentTimeElement document.getElementById(current-time);var currentTime new Date();currentTimeElement.textContent Curren…

ESP32CAM物联网教学02

ESP32CAM物联网教学02 物联网门锁 小智来到姑姑家门口&#xff0c;按了门铃&#xff1b;还在公司上班的姑姑用电脑给小智开了门&#xff0c;让他先进屋休息。小智对物联网门锁产生了兴趣&#xff1a;什么是物联网&#xff1f;为什么这么厉害&#xff1f; 初识物联网 我们在百…

Mac/Linux安装JMeter压测工具

Mac安装JMeter压测工具 介绍 Apache JMeter™应用程序是开源软件&#xff0c;是一个100%纯的Java应用程序&#xff0c;旨在加载测试功能行为和衡量性能。它最初是为测试Web应用程序而设计的&#xff0c;但后来扩展到其他测试功能。 我能用它做什么&#xff1f; Apache JMet…

SwanLinkOS首批实现与HarmonyOS NEXT互联互通,软通动力子公司鸿湖万联助力鸿蒙生态统一互联

在刚刚落下帷幕的华为开发者大会2024上&#xff0c;伴随全场景智能操作系统HarmonyOS Next的盛大发布&#xff0c;作为基于OpenHarmony的同根同源系统生态&#xff0c;软通动力子公司鸿湖万联全域智能操作系统SwanLinkOS首批实现与HarmonyOS NEXT互联互通&#xff0c;率先攻克基…

二叉树的最近公共祖先-二叉树

236. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; ​ 递归 lson、rson左右子树&#xff1b; 深度优先遍历&#xff0c;遍历到p或者q就返回ture&#xff1b; class Solution { public:TreeNode* ans;bool dfs(TreeNode* root, TreeNode* p, TreeNode* q){i…

什么游戏加速器好用 网游加速器排行榜

玩游戏经常遇到卡顿和网络延迟等问题&#xff0c;尤其是外服游戏&#xff0c;这时候就需要一个安全稳定快速的加速器&#xff0c;我个人比较推荐“深度加速器。这款款加速器在稳定性和加速效果上都非常不错&#xff0c;而且用户口碑也很好。 在选择加速器时&#xff0c;确实有很…

DGMamba: Domain Generalization via Generalized State Space Model论文笔记

文章目录 DGMamba: Domain Generalization via Generalized State Space Model摘要动机DGMamba设计隐藏状态抑制(HSS)语义感知补丁细化(SPR)免先验扫描域上下文交换上下文patch识别 实验结果 DGMamba: Domain Generalization via Generalized State Space Model paper: https:/…