快速失败“fail-fast”和安全失败“fail-safe”

news2024/9/21 12:39:08

目录

快速失败——fail-fast

异常原因

 正常原因

 安全失败“fail-safe”


快速失败——fail-fast

java的快速失败机制是java集合框架中的一种错误检测机制,当多个线程对集合中的内容进行修改时可能就会抛出ConcurrentModificationException异常。不仅仅在多线程状态下,在单线程中使用增强for循环一边遍历集合一边修改集合的元素也会抛出ConcurrentModificationException异常。例如:

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("python");
        list.add("c++");
        for (String s:list){
            list.remove(s);
        }
    }
}

抛出异常:

 正确做法使用迭代器的remove()方法,可正常删除

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("python");
        list.add("c++");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            iterator.next();//获取下一个元素
            iterator.remove();//删除当前元素
        }
    }

异常原因

首先查看list.remove()源码:

根据值找到对应的索引后调用fastRemove(index)方法 ,查看fastRemove(int index)方法

 发现第一个元素可以正常删除,但由于使用for-each循环,底层实际使用的是迭代器遍历当执行for (String s : list)时,Java会隐式地创建一个迭代器,并调用iterator()方法开始迭代。迭代过程:在每次循环中,Java会调用迭代器的next()方法获取下一个元素,并将其赋值给s。删除元素:然后执行list.remove(s),这实际上调用了remove()方法,删除了当前引用的元素。

 在调用next()时,里面包含checkForComodification();方法,该方法将modCount和expectedModCount进行比较。

checkForComodification()源码:

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

因此抛出了 ConcurrentModificationException异常。

 正常原因

由于迭代器使用的remove()和上面的remove()方法不同,源码:

 迭代器的remove()方法保证了expectedModCount = modCount;因此也保证了不会出现ConcurrentModificationException异常。

虽然在线程下,使用迭代器可以避免ConcurrentModificationException异常,但是在多线程下,使用迭代器的remove()方法还会报异常。

        这是因为modCount是在AbstractList类中定义的,而expectedModCount是在ArrayList内部类中定义,所以modCount是一个共享变量,而expectedModCount是属于线程各自的。

例如:当线程1更新了modCount属于自己的expectedModCount,而线程2只有看到modCount更新,自己的expectedModCount并没有更新,因此抛出ConcurrentModificationException异常。

 例如:

  1. ArrayList
  2. Vector
  3. HashMap
  4. HashSet
  5. LinkedHashMap
  6. LinkedHashSet

实现了"fail-fast"机制。

 安全失败“fail-safe”

在遍历集合时,不是直接在集合内容上进行访问,而是先复制原有集合内容,在复制的集合上进行遍历,在遍历时,对集合的修改是不会被迭代器检测到,所以不会抛出ConcurrentModificationException异常。

缺点:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间,原集合发生了修改,迭代器是无法访问到的。

在java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用:

例如:

  1. CopyOnWriteArrayList、
  2. CopyOnWriteArraySet
  3. ConcurrentHashMap

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

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

相关文章

[笔试强训day09]

文章目录 BC146 添加逗号DP2 跳台阶JZ61 扑克牌顺子解法一&#xff1a;排序模拟解法二&#xff1a;规律哈希 BC146 添加逗号 BC146 添加逗号 #include<iostream> #include<string>using namespace std;int main() {string s;cin>>s;string ans;for(int i0;i…

Docker学习笔记 - 创建自己的image

目录 基本概念常用命令使用docker compose启动脚本创建自己的image 使用Docker是现在最为流行的软件发布方式&#xff0c; 本系列将阐述Docker的基本概念&#xff0c;常用命令&#xff0c;启动脚本和如何生产自己的docker image。 在我们发布软件时&#xff0c;往往需要把我…

了解区块链基础设施,共同构建安全且强大的Sui网络

区块链基础设施的范畴很广&#xff0c;但其核心是那些直接与网络互动的计算机。这些实体通常被称为节点&#xff0c;分为不同的类型&#xff0c;例如维护完整区块链副本的全节点&#xff0c;以及作为共识决定者的验证节点。除了这两种类型之外&#xff0c;还有其他类型的节点&a…

链动3+1模式:引领企业创新发展的全新商业模式

在数字化时代&#xff0c;企业正积极寻求创新策略以应对竞争激烈的市场环境。链动31模式&#xff0c;作为一种前沿的商业模式&#xff0c;为企业带来了全新的发展机遇。本文将对链动31模式进行深度剖析&#xff0c;并与传统的链动21模式进行对比&#xff0c;以展现其独特魅力和…

大事件项目实战

初始化 创建项目 新建api_server文件夹为项目根目录&#xff0c;并在项目中运行如下的命令&#xff0c;初始化管理配置文件&#xff1a; npm init -y 运行如下的命令&#xff0c;安装特定版本的express: npm i express4.17.1 在项目根目录中新建app.js作为整个项目的入口…

Bootstrap5

Bootstrap5-容器 容器是Bootstrap—个基本的构建块&#xff0c;它包含、填充和对齐给定设备或视口中的內容。 Bootstrap 需要一个容器元素来包裏网站的内容 我们可以使用以下两个容器类&#xff1a; .container 类用于固定宽度并支持响应式布局的容器。.container-fluid 类用…

Linux下Qt Creator无法输入中文(已解决)

1. 首先确保安装了搜狗输入法&#xff0c;且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本&#xff0c;如下图所示&#xff0c;为基于Qt6的。 4. 进入源码目录&#xff0c;建立build文件夹&#xff0c;修改CMak…

常见电路的分类

举例&#xff1a;一个单片机控制电机驱动电路&#xff1a; 一般驱动部分和功率部分都是做到一起的 一、 驱动电路和功率电路&#xff1a; &#xff08;1&#xff09;电压高&#xff0c;电流大&#xff0c;需要与控制电路分开&#xff0c;并做好隔离保护&#xff08;光耦&…

【Hadoop】DataNode 数据盘进行磁盘DiskBalancer

目录 ​一、问题原因 二、DiskBalancer介绍 三、DiskBalancer实战 3.1 生成plan json文件 3.2 执行plan json文件 一、问题原因 阿里云事件磁盘损坏后&#xff0c;使用新磁盘进行了替换&#xff0c;或者当发现HDFS容量不够需要扩展空间时&#xff0c;由运维管理人员陆陆续…

CSS 【实战】 “四合院”布局

效果预览 页面要求&#xff1a; 上下固定高度左右固定宽度中间区域自适应宽高整个页面内容撑满全屏&#xff0c;没有滚动条 技术要点 使用 html5 语义化标签 header 网页内的标题区域nav 导航区域aside 侧边栏footer 页脚区域section 内容分区article 文章区域 清除浏览器默…

数据结构算法-堆(Heap)和优先队列

堆的概念 堆&#xff08;heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质&#xff1a; always greater than its child node/s and the key of the root node is the largest among all other nodes. This property…

XSKY CTO 在英特尔存储技术峰会的演讲:LLM 存储,架构至关重要

5 月 17 日&#xff0c;英特尔存储技术峰会在北京顺利举办。作为英特尔长期的合作伙伴&#xff0c;星辰天合受邀参加了此次峰会。星辰天合 CTO 王豪迈作为特邀嘉宾之一&#xff0c;作了主题为《LLM 存储&#xff1a;架构至关重要》的演讲&#xff0c;分享了大语言模型&#xff…

设计模式15——享元模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 享元模式&#xff08;Flyweigh…

开源金融AI代理平台FinRobot;支持多翻译引擎和模式的高效浏览器翻译开源插件;使用自然语言控制生成视频的通用世界模型

✨ 1: finrobot FinRobot 是一个基于大语言模型的开源金融AI代理平台&#xff0c;适用于多种金融应用。 FinRobot是一个综合性的AI代理平台&#xff0c;超越了原有的FinGPT&#xff0c;旨在满足金融行业的多元化需求。它集成了各种AI技术&#xff0c;不仅仅局限于语言模型&am…

VSCode中snippets(代码模板)的使用

首先安装Vue VSCode Snippets&#xff0c;在组件库中搜索并安装。 然后打开插件文件夹 文件夹名是 "作者名.vscode-插件名-版本号"组成的. C:\Users\Administrator\.vscode\extensions\sdras.vue-vscode-snippets-3.1.1\snippets 打开vue.json "prefix"…

C++系列-定位new表达式(placement-new)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 我们先来强调一个很关键的问题&#xff0c;那就是在new和delete中的一一对应的问题&#xff0c; 我们先来看一段代码&#xff1a; #include<iostream> using namespace …

K8s的CRI机制是什么?

1. 概述 进入 K8s 的世界&#xff0c;会发现有很多方便扩展的 Interface&#xff0c;包括 CRI, CSI, CNI 等&#xff0c;将这些接口抽象出来&#xff0c;是为了更好的提供开放、扩展、规范等能力。 K8s CRI(Container Runtime Interface) 是 K8s 定义的一组与容器运行时进行交…

Web3 游戏周报(5.19 - 5.25)

【5.19 - 5.25】Web3 游戏行业动态&#xff1a; Arbitrum 已开启 “2 亿枚 ARB 游戏催化剂计划”的提案投票。 STEPN 在官方 X 宣布将推出全新社交健身应用 STEPN GO。 Oasys 正式推出《足球小将》漫改 Web3 游戏《Captain Tsubasa-RIVALS-》。 Gala Games &#xff1a;已销…

8.Redis之hash类型

1.hash类型的基本介绍 哈希表[之前学过的所有数据结构中,最最重要的] 1.日常开发中,出场频率非常高. 2.面试中,非常重要的考点, Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中…

C++容器之向量(std::vector)

目录 1 概述2 使用实例3 接口使用3.1 construct3.2 assigns3.3 iterators3.4 capacity3.5 rezize3.6 reserve3.7 shrink_to_fit3.8 access3.9 assign3.10 push_back3.11 pop_back3.12 insert3.13 erase3.14 swap3.15 clear3.16 emplace3.17 emplace_back3.18 get_allocator1 概…