集合的fail-fast机制

(一) 什么是fail-fast?
       fail-fast是java集合的一种错误机制,当多个线程并发访问集合时,就有可能产生fail-fast事件,抛出ConcurrentModificationException异常。

(二) fail-fast如何产生?
       当一个线程对集合进行结构性的修改(如添加,删除,清空元素)时,而另一个线程访问集合,此时,expectedModCount 与 modCount不相等就会抛出ConcurrentModificationException异常。

以ArrayList的代码为例:

当用迭代器遍历ArrayList的集合时:

List<Integer> list = new ArrayList<>();
Iterator it = list.iterator();

调用的是ArrayList中的iterator()方法:

public Iterator<E> iterator() {
    return new Itr();
}

而Itr是ArrayList中的一个内部类,实现了Iterator接口:

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    //...其他代码略
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

       从上面代码可以发现,每次调用ArrayList的iterator()方法都将产生一个Itr实例,而每个Itr实例都有自己的 expectedModCount ,而 modCount 是ArrayList的属性。假如一个线程A调用了ArrayList的iterator()方法,此时expectedModCount = modCount。此后,在线程A遍历ArrayList的过程中,另一个线程B对ArrayList做了结构性修改, modCount +1 了,此时线程A的expectedModCount仍然是原来的值,代码中一判断modCount != expectedModCount,于是ConcurrentModificationException异常就被抛出了。

(三) 如何避免fail-fast?
       使用并发集合代替,比如用CopyOnWriteArrayList代替ArrayList。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值