1. 程式人生 > 其它 >java高併發之CopyOnWriteArrayList的那些事

java高併發之CopyOnWriteArrayList的那些事

注意:本文內容基於JDK11,不同版本會有差異

資料結構

CopyOnWriteArrayList本質上仍是一個數組,所以的實現都是基於陣列來進行的

原始碼解析

本文以add方法來解析CopyOnWriteArrayList,來看看它如何進行陣列儲存和實現高併發的。
CopyOnWriteArrayList的add實現方法要比ArrayList更加的直觀易懂。

    /**
     * 只能被getArray/setArray方法訪問
     * array為CopyOnWriteArrayList儲存資料的具體陣列
     */
    private transient volatile Object[] array;

   /**
    * CopyOnWriteArrayList會在初始化時,在預設的建構函式裡建立一個長度為0的陣列
    */
   public CopyOnWriteArrayList() {
       setArray(new Object[0]);
   }
   
   /**
     * add實現高併發的原理即使用了synchronized同步關鍵字
     * @param e
     * @return
     */
   public boolean add(E e){
        synchronized (lock){
            Object[] es = getArray();
            //第一次預設的初始化長度為0
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            setArray(es);
            return true;
        }
    }

    public E remove(int index){
        synchronized (lock){
            Object[] es = getArray();
            int len = es.length;
            E oldValue = elementAt(es, index);
            //用於判斷 需要移動的數量
            int numMoved = len - index - 1;
            Object[] newElements;
            if(numMoved == 0){
                newElements = Arrays.copyOf(es, len-1);
            }else {
                newElements = new Object[len - 1];
                //複製index之前的資料
                System.arraycopy(es, 0, newElements, 0, index);
                //複製index之後的資料
                System.arraycopy(es, index + 1, newElements, index,
                        numMoved);
            }
            setArray(newElements);
            return oldValue;
        }
    }