Java中的fail-fast(快速失败)策略

本文深入解析了快速失败(fail-fast)机制,阐述了其在Java集合框架中的应用,特别是ArrayList等集合类在并发修改时抛出ConcurrentModificationException的原因及源码分析。文章提供了避免该异常的有效策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是快速失败?

优先考虑异常情况,在程序发生异常情况时,直接终止程序,向用户抛出异常。

如何产生?

在迭代输出集合时,集合发生了结构上(增加,删除)的改变。产生java.util.ConcurrentModificationException异常。
java.util.的集合类 ,除了TreeMap大多都采用此策略(ArrayListVectorLinkedListHashSet)

例:ArrayList集合迭代输出时,添加"hhhh"的字符串

public class TestListIterator {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();  //创建好List,并给集合放入内容
        list.add("hello");
        list.add("world");
        list.add("hello");
        list.add("China");

        Iterator<String> iterator = list.iterator();    //取得list的迭代器
        //迭代输出list的内容
        while (iterator.hasNext()) {
            String str1 = iterator.next();
            list.add("hhhh");
            System.out.println(str1);
        }
    }
}

此时,程序会产生java.util.ConcurrentModificationException异常

产生原因-源码解析

  • 每调用一次add()方法向集合添加元素时,会使modCount这个变量值+1
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
  • 在调用list.iterator()迭代器对象时,会调用此方法,返回一个Itr()对象
    public Iterator<E> iterator() {
        return new Itr();
    }
  • private class Itr implements Iterator<E> {}这个方法中,有int expectedModCount = modCount;这个操作,将modCount赋给了expectedModCount
  • 在每次iterator.next()操作时,会调用next()方法,此方法中会再调用checkForComodification();方法。
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
  • 而此处会检验modCountexpectedModCount是否相等,因为进行了一次add操作,所以此时modCount已经+1了,两者不再相等,自然会抛出 ConcurrentModificationException
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

如何避免?

1.不要在迭代输出集合时修改集合内容,使集合结构改变。
2.使用iterator的修改方法。
3.使用fail-safe集合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值