什么是 fail-fast?什么是 fail-safe?

发布时间:2026/6/6 2:56:49

什么是 fail-fast?什么是 fail-safe? 核心结论一句话先记住它们是 Java 集合在被遍历时面对别人插队修改数据采取的两种完全相反的态度fail-fast快速失败脾气暴躁眼里不容沙子。遍历时只要发现有人偷偷改了数据立刻撂挑子不干抛出异常。fail-safe安全失败脾气温和佛系包容。你想改随你改老子复制一份副本慢慢看绝对不抛异常。 深度大白话解析1. 脾气暴躁的 fail-fast代表ArrayList、HashMap怎么实现的它们内部有一个“记账本”modCount。只要有人增加或删除了元素账本上的修改次数就会加 1。翻车现场你在用for-each兴高采烈地遍历元素每走一步都会对一下账本。如果突然发现账本数字变了说明有人在暗中修改它就会觉得“数据不安全了”当场甩脸子抛出经典的ConcurrentModificationException异常。写代码大坑很多人喜欢在for循环里直接调用list.remove()删元素这就是典型的“在遍历时改账本”百分之百直接报错。2. 稳如老狗的 fail-safe代表CopyOnWriteArrayList、ConcurrentHashMap怎么实现的它采用的是“影分身之术”。翻车现场当你开始遍历时它会偷偷把当前的数据复制一份副本。你接下来遍历的其实是这个“副本”而别人如果去修改、删除元素改的是“原本”。代价因为两者互不干扰所以它绝对不会抛异常。但缺点也很明显第一每次复制副本非常吃内存第二你遍历时读到的可能是“老数据”弱一致性别人新加进去的东西你可能看不见。️ 工作中怎么安全地“边遍历边删除”这是面试和写代码最常遇到的场景有三种正确姿势姿势一单线程推荐不要用集合自带的remove改用迭代器自带的iterator.remove()。因为迭代器自己删的时候会主动把账本对齐不会触发暴脾气。姿势二Java 8 推荐直接一行代码搞定list.removeIf(e - 条件)底层已经帮你封装好了安全机制。姿势三多线程推荐直接换用并发安全集合比如把ArrayList换成CopyOnWriteArrayList。 秒记口诀fail-fast账本不对就抛错直接删除必着魔fail-safe 复制副本不报错数据过期要记着。单线程删找迭代Iterator多线程用并发包

相关新闻