java ConcurrentModificationException剖析

Java学习笔记(4)

ConcurrentModificationException异常

  • 何时会出现ConcurrentModificationException异常?
  • ——对Vector,ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常
  • ArrayList的iterator()方法的具体实现(在ArrayList的父类AbstractList中):
  •         public Iterator<E> iterator() {
  •                 return new Iter();
  •         }
  • Itr的具体实现(还是在AbstractList类中,Itr是AbstractList的一个成员内部类):
  •       private class Itr implements Iterator<E> {
  •               int cursor = 0;
  •               int lastRet = -1;
  •               int expectedModCount = modCount;
  •               public boolean hasNext() {
  •                         return cursor != size();
  •               }
  •               public E next() {
  •                         checkForComodification();
  •                     try{
  •                     E next = get(cursor);
  •                     lastRet = cursor++;
  •                     return next;
  •                     } catch (IndexOutOdBoundsException) {
  •                         checkForComodification();
  •                         throw new NoSuchElementException();
  •                     }
  •               }
  •               public void remove() {
                           if (lastRet == -1)
  •                       throw new IllegalStateException();
  •                             checkForComodification();
  •                       try {
  •                       AbstractList.this.remove(lastRet);
  •                       if (lastRet < cursor)
  •                             cursor——;
  •                       lastRet = -1;
  •                       exceptionModCount = modCount;
  •                       } catch (IndexOutOfBoundsException e) {
  •                       throw new ConcurrentModificationException();
  •                       }
  •               }
  •               final void checkForComodification() {
                          if (modCount != exceptionModCount)
  •                       throw new ConcurrentModificationException();
  •               }
  • }
  • cursor: 表示下一个要访问的元素的索引
  • lastRet:表示上一个访问元素的索引
  • exceptionModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount
  • modCount是AbstractList类中的一个成员变量,表示对List的修改次数,ArrayList每次调用自己的add()方法和remove()方法就会对modCount进行加一操作
  • ArrayList中的remove()方法:
  • public boolean remove(Object o) {
  •     if (o == null) {
  •         for (int index = 0; index < size; index++)
  •             if (elementData[index] == null) {
  •                 fastRemove(index);
  •                 return true;
  •             }
  •     } else {
  •         for (int index = 0; index < size; index++)
  •             if (o.equals(elementData[index])) {
  •                 fastRemove(index);
  •                 return true;
  •             }
  •     }
  •     return false;
  • }
  •  
  • private void fastRemove(int index) {
  •     modCount++;
  •     int numMoved = size - index - 1;
  •     if (numMoved > 0)
  •         System.arraycopy(elementData, index+1, elementData, index,
  •                 numMoved);
  •     elementData[--size] = null; // Let gc do its work
  • }
  • 通过remove()方法删除元素最终是调用类fastRemove()方法,在fastRemove()方法中,首先对modCount进行加一操作,接下来就是删除元素操作,最后讲size进行减一操作,并将引用置为null以方便垃圾回收器进行回收工作
  • 如何解决多线程中的该异常:
  • 1)在使用iterator迭代的时候使用synchronized或者Lock进行同步
  • 2)使用并发容器CopyOnWriteArrayList代替Vector

作者: 海子
本博客中未标明转载的文章归作者 海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值