什么导致ConcurrentModificationException

时间:2018-05-18 17:49:49

标签: java collections concurrency iterator concurrentmodification

我正在阅读有关ConcurrentModificationException的内容。我为iterator找到了这段代码。任何人都可以解释实际上导致这个异常的原因。我只想为下面的逻辑提供一些理由。

public boolean hasNext() {
    return cursor != size;
}

@SuppressWarnings("unchecked")
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];
}

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
}

1 个答案:

答案 0 :(得分:0)

当您迭代它们时,您的基础元素数量正在改变大小,因此会引发异常。

请注意,此处的尝试不是从不可能的情况中恢复,而是尽可能早地和干净地“失败”。不抛出异常并使某些东西工作可能很容易,但行为是未定义的。这样做可以确保您的迭代器中没有编码错误,而不仅仅是从一个不可能的代码角中恢复。

// This line is getting the underlying array out from "this" ArrayList   
Object[] elementData = ArrayList.this.elementData; 

// I is the current value of your cursor.  Every time you call "next"
// this cursor is being incremented to get the next value
// This statement is asking if your current cursor extends beyond the
// end of the array, if it does then "Something" happened to make the array
// smaller while we weren't looking...
if (i >= elementData.length) 
    // To indicate that the elementData array has changed size outside of
    // our current iterator, throw an exception to the user.
    throw new ConcurrentModificationException();

因此,要导致这种情况发生,您将创建一个迭代器,然后减小数组列表的大小,然后调用“Next”。这应该给你一个CME