集合的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。

你可能感兴趣的:(集合)