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

前提,看一下这个

并发异常

代码中的具体逻辑

  1. 创建Iterator迭代器的时候,第一步首先对expectedModCount进行赋值
  2. int expectedModCount = modCount;
  3. 接下来调用hasNext方法,看是否有下一个对象,根据当前索引值是否等于迭代器长度进行控制
  4. 然后调用next()方法,返回list集合迭代器中当前索引值的元素.本方法中第一行代码是checkForComodification();检查模型修改次数是否和期望值相同
  5. 接下来调用迭代器的remove,add,set方法.在对元素进行修改的时候,对期望的修改次数进行了重新赋值,expectedModCount = modCount;
  6. 意思就是如果使用迭代器自身的增删改方法,迭代器是会进行重新进行赋值.然后进行下一次迭代的时候,next()方法的第一行检查就会通过.
  7. 但是如果使用集合本身的方法进行了增删改操作,modCount++,但是迭代器不会对expectedModCount重新进行赋值.进行下一次迭代的时候,进行到next()方法第一行的时候,检查不通过,报错并发修改异常.
  8. 源码如下
    包名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();
          }
      }
  }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值