Java中的Fail-Fast机制
什么是Fail-Fast机制
当多个线程同时对集合进行结构上的改变时,有可能引发Fail-Fast机制。
比如说两个Iterator,it1在遍历,it2删除了一个元素,那么就可能引发,程序就可能抛出ConcurrentModificationException异常。
但是这只是有可能抛出异常,所以不能编写一个依赖于此异常的程序。
Fail-Fast机制的产生原因
先看看ArrayList中的源码。
private class Itr 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();
    }
}
Iterator在调用remove()、next()的时候都会调用checkForComodification(),当modCount != expectedModCount的时候便会引发这个异常。
modCount一开始是0,每一个add操作和remove操作都会使他增加一。
当检测到modCount和期望的modCount不一致时,说明ArrayList已经在这个过程中被人修改。所以就抛出异常了。
解决办法
- 给抛出异常的方法加锁。
- 使用CopyOnWriteArray。这个类每add一次就new一个新的数组,所以原来的不会变。然而这样就看不到新的修改了。根据情景使用吧。