JAVA 源碼之線程安全List

CopyOnWriteArrayList
  • 線程安全版本ArrayList

  • 新增元素

    public boolean add(E e) {
            final ReentrantLock lock = this.lock;
            lock.lock();//進(jìn)行加鎖
            try {
                Object[] elements = getArray();
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len + 1);//元素組進(jìn)行拷貝
                newElements[len] = e;//將新元素加入到新數(shù)組中
                setArray(newElements);//新數(shù)組重新賦值予原數(shù)組
                return true;
            } finally {
                lock.unlock();//釋放鎖
            }
        }
    
    • 每新加一個元素都會發(fā)生一次全數(shù)組拷貝
    • 通過add(index,element)增加元素類似
    • 類似于ArrayList通過addAll進(jìn)行批量的增加效率要高于單個加入
  • 元素的刪除

        public E remove(int index) {
            final ReentrantLock lock = this.lock;
            lock.lock();//加鎖
            try {
                Object[] elements = getArray();
                int len = elements.length;
                E oldValue = get(elements, index);
                int numMoved = len - index - 1;
                if (numMoved == 0)//當(dāng)移除最后一個元素時
                    setArray(Arrays.copyOf(elements, len - 1));
                else {
                    Object[] newElements = new Object[len - 1];
                    System.arraycopy(elements, 0, newElements, 0, index);//分段拷貝
                    System.arraycopy(elements, index + 1, newElements, index,
                                     numMoved);
                    setArray(newElements);//元數(shù)據(jù)覆蓋
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
    
    • 發(fā)生一次數(shù)組對象拷貝
    • 直接移除元素時,先找到其索引,然后通過以上方法進(jìn)行移除
    • 同樣批量刪除的效率高于單個刪除
  • 內(nèi)部類

    • COWIterator
      • next 向后訪問
      • previous 向前訪問
      • nextIndex 查看下一個索引值
      • previousIndex 前一個索引值
      • 不支持操作:remove,set,add
      • 取值過程不進(jìn)行mod的檢查
    • Spliterators.spliterator
    • COWSubList
  • 特點

    • 變更操作基本是先拷貝出一個副本,操作副本完成后,用副本更新原數(shù)據(jù)
SynchronizedList
  • 線程安全List

  • 在get/set/add/remove/indexOf/sort 內(nèi)部對象進(jìn)行加鎖處理

            public E get(int index) {
                synchronized (mutex) {return list.get(index);}
            }
    
  • 加鎖粒度比較大

兩者對比
  • CopyOnWriteArrayList在數(shù)據(jù)讀上占據(jù)優(yōu)勢
  • CopyOnWriteArrayList需要更大的內(nèi)存空間
  • SynchronizedList使用迭代器需要自己進(jìn)行線程的同步
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容