java fail-fast机制

概述

fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。

该机制设计的初衷

在遍历集合元素的过程中,是不希望集合被修改的;不然会产生许多问题,比如:
arraylist在遍历的过程中,元素被删除。此时后面的元素会进行移位,来填补空出来的位置;元素移位不是原子操作,相反元素较多的情况下,这个过程消耗的时间不短;元素位置调整的过程中,又进行遍历,肯定会产生不少问题,比如漏掉对元素的访问。
为此只要检测到集合被修改过,就应该快速的失败,并抛出异常。

该机制的实现

每个集合类都有一个成员变量,private transient int modCount = 0;
从字面意思代表集合被修改的次数,实际上就是代表数据的版本。每进行一次修改集合的操作(比如,list中的add,remove;map中的put等),modCount的值加一。
以Arraylist的代码为例:

    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

当遍历集合的时候,会用expectedModCount来保存modCount,然后每次访问元素的时候,都会判断两者是否相等,来检查集合是否被修改过。下面是ArrayList创建的迭代器。

    public Iterator<E> iterator() {
        return new Itr();
    }
    // Itr是内部类,可以访问到ArrayList的成员变量
    // 代码有删除
    private class Itr implements Iterator<E> {
        // modCount是ArrayList的成员变量,创建Itr会存储当前modCount
        // 后续遍历元素时,通过对比两者来判断集合是否修改过
        int expectedModCount = modCount;
        @SuppressWarnings("unchecked")
        public E next() {
            // 判断集合是否修改过
            checkForComodification();
            int i = cursor;
            Object[] elementData = ArrayList.this.elementData;
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        // iterator自己修改集合不会产生问题,因为调用者清楚自己在干啥
        // 删除元素的同时修改modCount,这样同时创建出来的两个迭代器,
        // 一个修改后,另外一个能够感知到
        public void remove() {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        }
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值