Java Fail-Fast 与 Fail-Safe 特性

一、前言

在 Java 的集合结构中,如果我们同时进行遍历(for-each, iterator)和集合修改(add, set, remove…)操作时,就有可能发生异常。例如,线程 T1 在对集合进行遍历,而此时线程 T2 对集合进行添加元素;亦或者线程 T1 在对集合进行遍历的过程中,进行删除元素操作。

不同的集合在遇到上述这种情况时,会有不同的处理。按照处理的不同,划分为 Fail-Fast 和 Non-Fail-Fast(下文统称为 Fail-Safe)两类。前者不允许在迭代的过程中对集合进行增删操作,否则抛出 ConcurrentModificationException 异常;后者则允许这种操作,不会抛出异常。

注:本处的“对集合进行增删操作”指的是对集合自身的操作,而非借助 iterator 的操作。

二、Fail-Fast

Fail-Fast 类型的数据结构,在进行迭代时如果检测到集合对象发生了结构性修改会立即抛出 ConcurrentModificationException,结构性修改指的是对该集合对象进行添加、删除或更新元素的操作。ArrayList, HashMap 返回的迭代器就是典型的 Fail-Fast。

2.1 样例展示

import java.util.*;

public class FailFastExample {
   
    public static void main(String[] args) {
   
        Map<String, String> cityCode = new HashMap<>();
        cityCode.put("Delhi", "India");
        cityCode.put("Moscow", "Russia");
        cityCode.put("New York", "USA");  // 此时 HashMap 对象的 modCount=3

        // 返回 Iterator 对象时,会使用字段 expectedModCount 记录当前 HashMap 对象的 modCount
        Iterator<String> iterator = cityCode.keySet().iterator();

        while (iterator.hasNext()) {
   
            // 每次调用 iterator.next() 时都会检查 expectedModCount 是否与 modCount 相等,若不等则抛出 ConcurrentModificationException
            System.out.println(cityCode.get(iterator.next()));

            // 往 Map 对象添加元素,迭代器在下一次调用 next() 时会抛出异常
            cityCode.put
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值