【Java】快速失败策略

本文深入解析快速失败(fail-fast)策略,阐述其在Java集合类中的应用,如ArrayList、Vector等,通过实例说明并发修改异常(ConcurrentModificationException)的产生原因及处理方法。

快速失败策略(fail - fast)

即为优先处理产生异常的情况,当异常情况发生时,直接向用户抛出异常,程序终止。
例:

public static int div(int a,int b){
        if (b == 0){
            throw new IllegalArgumentException("除数不能为0");
        }
        return a / b;
    }

当我们执行这种代码的时候会出现如下情况:

public class ListIteratorTest2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //modcount = 1
        list.add("hello");
        //modcount = 2
        list.add("java");
        //modcount = 3
        list.add("hello");
        //modcount = 4
        list.add("fwb");
        // expectedModCount = modcount (4)
        Iterator<String> iterator = list.iterator();//取得迭代器
        while(iterator.hasNext()){
            String str = iterator.next();
            if (str.equals("fwb")){
                list.remove(str);
                //modcount++(5)
            }
            System.out.println(str);
        }
    }
}

在这里插入图片描述

java.util.ConcurrentModificationException,产生原因:当迭代输出集合时,并发修改了集合的结构。
源码中的 protected transient int modCount 记录了当前集合被修改的(add,remove等方法)次数。.
源码中当使用迭代器的时候,会执行这样一个代码int expectedModCount = modCount;
以及这个方法:

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

当我们执行: list.remove(str);这行代码的时候 modCount++,则modCount != expectedModCount,产生了异常,之所以前四个可以正常输出是因为在remove之后modcount才加1,所以在此之前都是正常的。(见代码)
意义:例如有3个线程在同时运行,2个线程在读取ArrayList的内容,1个线程修改了该集合的值,那么这两个线程读取的内容就有可能是不正确的。fail—fast机制保证集合在多线程场景下读到最新的值。 java.util 的集合类大多都采用此策略(如:ArrayList、Vector、LinkedList、HashSet,读写都在同一个副本中)
与其相关的有:
fail—safe:
java.util.concurrent:CopyOnWriteArrayList/conCurrentHashMap
CopyOnWriteArrayList采用读写分离,所有的读为异步操作,写为同步操作,且读写不在同一个副本。
如何处理:
1.迭代输出的时候,不要修改集合的内容
2.使用迭代器的修改方法(在源码中,他虽然最终调用的还是ArrayList的方法。但是在此之后将expectModCount重新赋值了一次)

if (str.equals("fwb")){
   //list.remove(str);
   iterator.remove();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我顶得了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值