ArrayList的ConcurrentModificationException异常和多线程下的异常

1、ConcurrentModificationException

ArrayList源码看为何出现异常:html

public class ArrayList<e> extends AbstractList<e>
        implements Cloneable, Serializable, RandomAccess {
         
         
         @Override public boolean remove(Object object) {
        Object[] a = array;
        int s = size;
        if (object != null) {
            for (int i = 0; i < s; i++) {
                if (object.equals(a[i])) {
                    System.arraycopy(a, i + 1, a, i, --s - i);
                    a[s] = null;  // Prevent memory leak
                    size = s;
                    modCount++;  // 只要删除成功都是累加
                    return true;
                }
            }
        } else {
            for (int i = 0; i < s; i++) {
                if (a[i] == null) {
                    System.arraycopy(a, i + 1, a, i, --s - i);
                    a[s] = null;  // Prevent memory leak
                    size = s;
                    modCount++;  // 只要删除成功都是累加
                    return true;
                }
            }
        }
        return false;
    }   
 
 
    @Override public Iterator<e> iterator() {
        return new ArrayListIterator();
    }   
         
    private class ArrayListIterator implements Iterator<e> {
          ......
    
          // 全局修改总数保存到当前类中
        /** The expected modCount value */
        private int expectedModCount = modCount;
 
        @SuppressWarnings("unchecked") public E next() {
            ArrayList<e> ourList = ArrayList.this;
            int rem = remaining;
               // 若是建立时的值不相同,抛出异常,
            if (ourList.modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            if (rem == 0) {
                throw new NoSuchElementException();
            }
            remaining = rem - 1;
            return (E) ourList.array[removalIndex = ourList.size - rem];
        }   
         
          ......
     }
}

  由上可知,若是遍历中做get,remove操做都会改变modCount的值,可是此时expectedModCount仍是保存之前的modCount的值,确定不相等,抛出异常。java

2、多线程下的异常

一、发生 ArrayIndexOutOfBoundsException 异常;数组

  问题是出如今多线程并发访问下,因为没有同步锁的保护,形成了 ArrayList 扩容不一致的问题。安全

二、程序正常运行,输出了少于实际容量的大小;多线程

  这个也是多线程并发赋值时,对同一个数组索引位置进行了赋值,因此出现少于预期大小的状况。并发

三、程序正常运行,输出了预期容量的大小;dom

  这是正常运行结果,未发生多线程安全问题,但这是不肯定性的,不是每次都会达到正常预期的。ide

3、线程安全的CopyOnWriteArrayList

Java并发集合(一)-CopyOnWriteArrayList分析与使用post

相关文章
相关标签/搜索