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
一、发生 ArrayIndexOutOfBoundsException 异常;数组
问题是出如今多线程并发访问下,因为没有同步锁的保护,形成了 ArrayList 扩容不一致的问题。安全
二、程序正常运行,输出了少于实际容量的大小;多线程
这个也是多线程并发赋值时,对同一个数组索引位置进行了赋值,因此出现少于预期大小的状况。并发
三、程序正常运行,输出了预期容量的大小;dom
这是正常运行结果,未发生多线程安全问题,但这是不肯定性的,不是每次都会达到正常预期的。ide