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

相關文章
相關標籤/搜索