Fail-fast 機制分析

huangxy發表於2020-03-19

fail-fast 機制介紹

fail-fast(快速失敗)機制是集合中比較常見的錯誤檢測機制,防止在對集合進行遍歷的時候,出現意料之外的修改,導致意想不到的結果

fail-fast 產生原因

下面通過一個簡單的例子分析fail-fast產生的原因

@Test
public void failFastTest(){
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    Iterator iterator = list.iterator();
	while (iterator.hasNext()) {
		System.out.println(iterator.next());
		list.add("4");
	}
}
複製程式碼

程式碼執行結果

報錯資訊

通過控制檯輸出報錯資訊,可以看到ConcurrentModificationException異常是呼叫iterator.next()方法的時候跑丟擲的,進入到next()方法

public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}
複製程式碼

可以看到next()方法在每次呼叫的時候,會先呼叫checkForComdification()方法,進入到checkForComdification()方法

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}
複製程式碼

程式碼比較簡單,當modCountexpectedModCount不相等的時候,就丟擲ConcurrentModficationException異常

modCountArrayList中的一個成員變數,表示的是ArrayList被修改的次數,每次呼叫ArrayLsitadd(E e)/remove()方法時,modCount++

expectedModCountArrayList中的一個內部類Itr的成員變數,其值是在ArrayList.iterator()方法被呼叫的時候初始化的,取初始化那一刻的modCount的值。表示的是ArrayList預計被修改的次數

當我們在對ArrayList進行迭代的時候,對集合進行修改,就會產生modeCount != expectedModCount,程式丟擲ConcurrentModficationException

fail-fast 更多是在多執行緒場景下產生的,上面的例子只是為了簡單講解 fail-fast 產生的原因

公眾號

掃碼關注我,一起學習,一起進步

在這裡插入圖片描述

相關文章