【Java】快速失败(fail-fast)与安全失败(fail-safe)

1、fail-fast:
ConcurrentModificationException异常。
维基百科中,对快速失败是这样解释的:
快速失败系统是一种可以立即报告任何可能表明故障的情况的系统。通常设计用于系统正常操作,而不是试图继续可能存在缺陷的过程。这种设计通常会在操作中的多个点检查系统状态,以便于及早检测到错误。快速失败得到职责是检测错误,然后让系统的下一个最高级别处理错误。
总结:快速失败机制是Java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能回产生快速失败事件。
源码分析:快速失败既然是在集合中操作迭代器产生的,那么我们来看一下迭代器的源码

private class IteratorTest implements Iterator<E> {
        int cursor;
        int lastRet = -1;
        int expectedModCount = ArrayList.this.modCount;
        public boolean hasNext() {
            return (this.cursor != ArrayList.this.size);
        }
        public E next() {
            checkForComodification();
        }
        public void remove() {
            if (this.lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
        }
        final void checkForComodification() {
            if (ArrayList.this.modCount == this.expectedModCount)
                return;
            throw new ConcurrentModificationException();
        }
}

由上面迭代器的源码可以看到,在nextremove方法中都有调用checkForComodification() 方法。而该方法则是判断modCount 是否等于expectedModCount。而expectedModCount已经在迭代器中定义了,所以只有modCount会改变,modCount是在AbstractList 中定义的,为全局变量,只有当集合中元素的个数进行改变的时候它的值才会改变,然后产生快速失败。我们可以用加sync的方式来进行解决。
2、fail-safe:
在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。需要注意的是,安全失败并不会抛出异常,也不会比较modCount和expectedModCount值。并且安全失败继承的接口是List, 快速失败继承的接口是AbstractList。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值