Java中快速失败 (fail-fast) 机制

快速失败 (fail-fast) 是什么?

fail-fast 是一种错误检测机制,它的核心思想是在检测到错误条件时立即抛出异常,以防止程序进一步执行可能导致错误的操作。通常用于迭代器以及集合类中。当你用迭代器对集合进行迭代时,如果集合在迭代过程中被修改了,就会立即抛出ConcurrentModificationException。这种修改可能是添加、删除集合中的元素。快速失败机制通过立即通知程序员发生了并发修改,避免了未定义行为的出现。

案例 1

public static void main(String[] args) {ArrayList<Integer> numbers = new ArrayList<>();numbers.add(1);numbers.add(2);numbers.add(3);// 创建迭代器Iterator<Integer> iterator = numbers.iterator();// 在迭代器创建后对列表进行修改numbers.add(4);// 再次输出迭代器的值while (iterator.hasNext()) {System.out.println(iterator.next()); // 第一次进来时报错}}
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)at java.util.ArrayList$Itr.next(ArrayList.java:861)at org.swp.controller.UserContext.main(UserContext.java:15)

迭代器创建之后,通过调用numbers.add(4)修改了列表的结构,从而在随后的迭代中引发了ConcurrentModificationException

案例 2

public static void main(String[] args) {ArrayList<Integer> numbers = new ArrayList<>();numbers.add(1);numbers.add(2);numbers.add(3);// 其实在代码编译的时候for循环会被编译成迭代器for(Integer a : numbers){ // 第二次遍历时报错if(a.equals(1)){numbers.remove(a);}}
}
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)at java.util.ArrayList$Itr.next(ArrayList.java:861)at org.swp.controller.UserContext.main(UserContext.java:15)

当迭代器正在遍历numbers列表时,你尝试从中删除元素。这会改变列表的结构,因此触发了ConcurrentModificationException

如何避免这个异常

要修复这种错误,你需要确保在迭代期间不直接修改集合。如果你必须修改集合,你有几个选项:

  • 在迭代期间收集要删除的元素,然后在迭代后删除它们。
  • 使用迭代器提供的remove()方法来移除元素。
  • 使用支持并发修改的集合类,如ConcurrentHashMap或CopyOnWriteArrayList。
  • 在for循环中引入变量,而不是遍历集合
ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);for(int i=0;i<list.size();i++) {Integer item = list.get(i);if (item.equals(3)) {list.remove(i);//为了效率,这里最好不要用list.remove(item)}}

不引用迭代器方法进行删除,可以防止ConcurrentModificationException

Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {Integer a = iterator.next();if (a.equals(1)) {iterator.remove();}
}

使用迭代器的remove()方法来删除当前元素可以防止ConcurrentModificationException,因为这样做不会破坏迭代器的内部状态。

public static void main(String[] args) {CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();list.add(1);list.add(2);list.add(3);Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {Integer a = iterator.next();if (a.equals(1)) {list.remove(a);}}System.out.println(list);}

CopyOnWriteArrayList 源码推荐阅读文章
文章链接: 解析CopyOnWriteArrayList的高效读取与安全更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/200923.shtml

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

相关文章

[组合数学]LeetCode:2954:统计感冒序列的数目

作者推荐 [二分查找]LeetCode2040:两个有序数组的第 K 小乘积 题目 给你一个整数 n 和一个下标从 0 开始的整数数组 sick &#xff0c;数组按 升序 排序。 有 n 位小朋友站成一排&#xff0c;按顺序编号为 0 到 n - 1 。数组 sick 包含一开始得了感冒的小朋友的位置。如果位…

YOLOv8改进 | 2023 | 将RT-DETR模型AIFI模块和Conv模块结合替换SPPF(全网独家改进)

一、本文介绍 本文给大家带来是用最新的RT-DETR模型中的AIFI模块间去替换YOLOv8中的SPPF。RT-DETR号称是打败YOLO的检测模型&#xff0c;其作为一种基于Transformer的检测方法&#xff0c;相较于传统的基于卷积的检测方法&#xff0c;提供了更为全面和深入的特征理解&#xff…

Go语言基础面经

1.go语言编程的好处是什么 编译和运行都很快。 在语言层级支持并行操作。 有垃圾处理器。 内置字符串和 maps。 函数是 go 语言的最基本编程单位。 2.说说go语言的select机制 select 机制用来处理异步 IO 问题 select 机制最大的一条限制就是每个 case 语句里必须是一个…

Python下TCP编程

​ 在Python中使用socket模块的socket函数可以完成&#xff0c;语法格式如下&#xff1a; ssocket.socket(AddressFamily, Type)函数socket.socket创建一个socket&#xff0c;返回该socket的描述符。该函数带有两个参数。 Address Family&#xff1a;可以选择AF_INET&#xf…

Kafka 消费者 API 指南:深入探讨消费者的实现与最佳实践

Kafka 消费者 API 是连接应用程序与 Kafka 集群之间的关键接口&#xff0c;用于从 Kafka 主题中拉取消息并进行处理。本篇文章将深入探讨 Kafka 消费者 API 的核心概念、用法&#xff0c;以及一些最佳实践&#xff0c;帮助你构建高效、可靠的消息消费系统。 1. Kafka 消费者 A…

根据字符出现频率排序 (哈希表,map,cmp,sort,遍历)

它要我们统计每个字符出现的个数&#xff0c;所以会想到使用map有一个键值对&#xff0c;一个key为char类型&#xff0c;一个value为int类型&#xff0c;这样我们可以得到每个字符的出现次数&#xff0c;又因为它让出现次数多的先输出&#xff0c;所以会想到使用sort从大到小排…

Python查看文件列表

os.listdir 是 Python 的一个内置函数&#xff0c;用于列出指定目录中的所有文件和子目录。它接受一个字符串参数&#xff0c;即要列出内容的目录的路径。 列出当前工作目录中的所有文件和子目录 files_and_dirs os.listdir() print(files_and_dirs) 列出指定目录中的所…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之文件管理(3)》(24)

《Linux操作系统原理分析之文件管理&#xff08;3&#xff09;》&#xff08;24&#xff09; 7 文件管理7.5 文件存储空间的管理7.6 文件的共享和保护7.6.1 文件存取控制7.6.2 文件共享的实现方法7.6.3 文件的备份转储 7 文件管理 7.5 文件存储空间的管理 位示图 对每个磁盘…

力扣295. 数据流的中位数

优先队列 思路&#xff1a; 中位数是排序中间的数值&#xff1a;S1.M.S2可以使用两个优先队列来存放两边的数值&#xff0c;总是使得左侧的堆顶是最大的&#xff0c;右侧的堆顶是最小的&#xff0c;即使用大顶堆存放 S1&#xff0c;使用小顶堆存放S2&#xff0c;使得两个队列的…

【S32K3环境搭建】-0.1-安装S32 Design Studio for S32 Platform 3.5

目录&#xff08;S32DS安装步骤详细&#xff09; 1 安装S32 Design Studio for S32 Platform 3.5准备工作 2 下载S32 Design Studio for S32 Platform 3.5安装包 2.1 获取S32DS的License许可 3 安装S32 Design Studio for S32 Platform 3.5 4 打开S32 Design Studio for S…

uniapp基于u-grid-item九宫格实现uCharts秋云图表展示

uniapp基于uView的UI组件u-grid-item九宫格实现uCharts秋云可视化图表展示 这里使用uView的u-grid-item九宫格组件去显示图标排列 九宫格可以做成多列&#xff0c;移动设备上可以通过左右滑动进行展示 <template><div><div style"text-align: center;font…

Apollo新版本Beta技术沙龙

有幸参加Apollo开发者社区于12月2日举办的Apollo新版本(8.0)的技术沙龙会&#xff0c;地址在首钢园百度Apollo Park。由于去的比较早&#xff0c;先参观了一下这面的一些产品&#xff0c;还有专门的讲解&#xff0c;主要讲了一下百度无人驾驶的发展历程和历代产品。我对下面几个…

正则表达式(4):连续次数的匹配

正则表达式&#xff08;4&#xff09;&#xff1a;连续次数的匹配 小结 本博文转载自 在本博客中&#xff0c;”正则表达式”为一系列文章&#xff0c;如果你想要从头学习怎样在Linux中使用正则&#xff0c;可以参考此系列文章&#xff0c;直达链接如下&#xff1a; 在Linux中…

C语言进阶之路-指针、数组等混合小boss篇

目录 一、学习目标&#xff1a; 二、指针、数组的组合技能 引言 指针数组 语法 数组指针 三、勇士闯关秘籍 四、大杂脍 总结 一、学习目标&#xff1a; 知识点&#xff1a; 明确指针数组的用法和特点掌握数组指针的用法和特点回顾循环等小怪用法和特点 二、指针、数…

2023-12-05 Qt学习总结 (AI辅助) 未完待续

点击 <C 语言编程核心突破> 快速C语言入门 Qt学习总结 前言一 Qt是什么二 Qt开发工具链三 Qt编程涉及的术语和名词四 Qt Creator使用五 hello Qt!六 Qt控件和事件七 Qt信号和槽八 Qt自定义信号和槽九 Qt QObject基类十 QWidget基类十一 QMainWindow基类十二 QLabel文本框…

Java中迭代Map和List最简单直接办法

这里介绍可以迭代 Map 和 List 最简单直接办法&#xff0c;代码量最少。 方法 1&#xff1a;标准for方法&#xff1a; List&#xff1a; for(String item:sList) {..} Map&#xff1a; for(Map.Entry<String, String> sEntry : sMap.entrySet()){..} 方法 2&#xff…

02 硬件知识入门(电容)

1 电容的定义和主要参数 1.1 电容的符号 1.2 电容的作用 1.3 电容滤波 1.4 电容的标号命名规则 1.5电容的&#xff08;串联并联&#xff09;计算公式 与电阻的计算公式相反 1.5.1 电容的并联 1.5.2 电容的串联

JavaScript 之数组

数组之间 合并问题 1 concat()方法 concat()方法可以将多个数组合并成一个新的数组。 const array1[1,2,3] const array2[4,5,6] const arrayListarray.concat(array2) //打印[1,2,3,4,5,6] 2 拓展运算符 拓展运算符是将一个数组拆分为单个元素&#xff0c;并将其添加到另…

上传文件接口的创建_FastAPI

上传文件接口的创建 功能描述代码效果演示与注意事项 功能描述 前端用户需要上传文件至平台&#xff0c;就比如CSDN的上传资源部分&#xff0c;都是一样的功能逻辑&#xff0c;想要实现这个功能其实并不难。 这里以上传的JSON格式文件为例&#xff0c;其他格式文件的话可以自…

用python找到音乐数据的位置,并实现音乐下载

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 需求分析: 有什么需求要实现? 这些需求可以用什么技术实现? 找到音乐数据的位置, 分析 不同音乐的链接有何规律?https://lx-sycdn.kuwo.cn/b784688662c82db8…