[源码解读]并发修改异常ConcurrentModificationException

    科技2022-08-19  100

    前提,看一下这个

    并发异常

    代码中的具体逻辑

    创建Iterator迭代器的时候,第一步首先对expectedModCount进行赋值int expectedModCount = modCount;接下来调用hasNext方法,看是否有下一个对象,根据当前索引值是否等于迭代器长度进行控制然后调用next()方法,返回list集合迭代器中当前索引值的元素.本方法中第一行代码是checkForComodification();检查模型修改次数是否和期望值相同接下来调用迭代器的remove,add,set方法.在对元素进行修改的时候,对期望的修改次数进行了重新赋值,expectedModCount = modCount;意思就是如果使用迭代器自身的增删改方法,迭代器是会进行重新进行赋值.然后进行下一次迭代的时候,next()方法的第一行检查就会通过.但是如果使用集合本身的方法进行了增删改操作,modCount++,但是迭代器不会对expectedModCount重新进行赋值.进行下一次迭代的时候,进行到next()方法第一行的时候,检查不通过,报错并发修改异常.源码如下 包名java.util.AbstractList /** * {@inheritDoc} * * <p>This implementation returns a straightforward implementation of the * {@code ListIterator} interface that extends the implementation of the * {@code Iterator} interface returned by the {@code iterator()} method. * The {@code ListIterator} implementation relies on the backing list's * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)} * and {@code remove(int)} methods. * * <p>Note that the list iterator returned by this implementation will * throw an {@link UnsupportedOperationException} in response to its * {@code remove}, {@code set} and {@code add} methods unless the * list's {@code remove(int)}, {@code set(int, E)}, and * {@code add(int, E)} methods are overridden. * * <p>This implementation can be made to throw runtime exceptions in the * face of concurrent modification, as described in the specification for * the (protected) {@link #modCount} field. * * @throws IndexOutOfBoundsException {@inheritDoc} */ public ListIterator<E> listIterator(final int index) { rangeCheckForAdd(index); return new ListItr(index); } private class Itr implements Iterator<E> { /** * Index of element to be returned by subsequent call to next. */ int cursor = 0; /** * Index of element returned by most recent call to next or * previous. Reset to -1 if this element is deleted by a call * to remove. */ int lastRet = -1; /** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */ int expectedModCount = modCount;//第一步 public boolean hasNext() {//第二步 return cursor != size(); } public E next() {//第三步 checkForComodification();//3.1modCount模型修改次数检查 try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount;//增删改操作者,模型修改次数重新赋值 } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { cursor = index; } public boolean hasPrevious() { return cursor != 0; } public E previous() { checkForComodification(); try { int i = cursor - 1; E previous = get(i); lastRet = cursor = i; return previous; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public int nextIndex() { return cursor; } public int previousIndex() { return cursor-1; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; AbstractList.this.add(i, e); lastRet = -1; cursor = i + 1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
    Processed: 0.015, SQL: 9