CopyOnWriteArrayList婧愮爜闃呰

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CopyOnWriteArrayList婧愮爜闃呰相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/VID' title='VID'>VID   call   dex   闅忔満   boolean   椤哄簭   str   蹇収   state   

1銆丆opyOnWrite瀹瑰櫒鏈変袱绉嶏細
路CopyOnWriteArrayList
路CopyOnWriteArraySet
CopyOnWrite瀹瑰櫒绠€绉癈OW瀹瑰櫒锛屽叾鐗圭偣濡備笅锛?br/>1锛塁opyOnWrite瀹瑰櫒鍗冲啓鏃跺鍒剁殑瀹瑰櫒銆?br/>2锛夐€氫織鐨勭悊瑙f槸褰撴垜浠線涓€涓鍣ㄦ坊鍔犲厓绱犵殑鏃跺€欙紝涓嶇洿鎺ュ線褰撳墠瀹瑰櫒娣诲姞锛岃€屾槸鍏堝皢褰撳墠瀹瑰櫒杩涜Copy锛屽鍒跺嚭涓€涓柊鐨勫鍣紝鐒跺悗鏂扮殑瀹瑰櫒閲屾坊鍔犲厓绱狅紝娣诲姞瀹屽厓绱犱箣鍚庯紝鍐嶅皢鍘熷鍣ㄧ殑寮曠敤鎸囧悜鏂扮殑瀹瑰櫒锛岃鏃堕兘鏄闂棫瀹瑰櫒锛屽啓鏃舵墠闇€瑕佸姞閿併€?br/>3锛夎繖鏍峰仛鐨勫ソ澶勬槸鎴戜滑鍙互瀵笴opyOnWrite瀹瑰櫒杩涜骞跺彂鐨勮锛岃€屼笉闇€瑕佸姞閿侊紝鍥犱负褰撳墠瀹瑰櫒涓嶄細娣诲姞浠讳綍鍏冪礌銆?br/>鎵€浠opyOnWrite瀹瑰櫒涔熸槸涓€绉嶈鍐欏垎绂荤殑鎬濇兂锛岃鍜屽啓涓嶅悓鐨勫鍣ㄣ€?br/>2銆丆opyOnWriteArrayList绫荤户鎵跨粨鏋勶細
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable锛?/p>

3銆佸浜嶤opyOnWriteArrayList涓昏鏌ョ湅浠ヤ笅鍑犱釜鏂规硶锛?br/>路鍒涘缓锛欳opyOnWriteArrayList()
路娣诲姞鍏冪礌锛氬嵆add(E)鏂规硶
路鑾峰彇鍗曚釜瀵硅薄锛氬嵆get(int)鏂规硶
路鍒犻櫎瀵硅薄锛氬嵆remove(E)鏂规硶
路閬嶅巻鎵€鏈夊璞★細鍗砳terator()锛屽湪瀹為檯涓洿甯哥敤鐨勬槸澧炲己鍨嬬殑for寰幆鍘诲仛閬嶅巻銆?/p>

4銆佹瀯閫犳柟娉旵opyOnWriteArrayList锛屽叾鐩稿叧浠g爜锛?br/>/* 鍙兘 getArray/setArray璁块棶鏁扮粍. /
private volatile transient Object[] array;

/**
 * 鑾峰彇鏁扮粍
 */
final Object[] getArray() {
    return array;
}

/**
 * 璁剧疆鏁扮粍
 */
final void setArray(Object[] a) {
    array = a;
}

/**
 *鍒涘缓涓€涓┖鐨勬暟缁勶紝Object[0]锛岃€孉rrayList鍒欐槸10
 */
public CopyOnWriteArrayList() {
    setArray(new Object[0]);
}

5銆佹坊鍔犲厓绱?br/>public boolean add(E e) {

    final ReentrantLock lock = this.lock;
    lock.lock(); //鑾峰彇鍏ㄥ眬閿侊紙鐙崰閿侊級锛岃幏鍙栦笉鍒板垯闃诲
    try {
        Object[] elements = getArray(); //鑾峰彇褰撳墠鐨勬暟缁?        int len = elements.length;
                     /*
         * Arrays.copyOf(elements, len + 1)鐨勫ぇ鑷存墽琛屾祦绋嬶細
         * 1锛夊垱寤烘柊鏁扮粍锛屽閲忎负len+1锛?         * 2锛夊皢鏃ф暟缁別lements鎷疯礉鍒版柊鏁扮粍锛?         * 3锛夎繑鍥炴柊鏁扮粍
         */
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e; //鏂版暟缁勭殑鏈熬鍏冪礌璁炬垚e
        setArray(newElements); //灏嗘棫鏁扮粍鎸囧悜鏂版暟缁勫紩鐢?        return true;
    } finally {
        lock.unlock();
    }
}

    6銆佽幏鍙栨寚瀹氬厓绱?
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
    return (E) a[index];
}

/**
 * {@inheritDoc}
 *
 * @throws IndexOutOfBoundsException {@inheritDoc}  //鎵句笉鍒版寚瀹氱殑鍏冪礌鍒欐姏鍑哄紓甯? */
public E get(int index) {
    return get(getArray(), index); //鍏堣幏鍙栨暟缁勶紝鍦ㄨ鍙栨寚瀹氫綅缃殑鍏冪礌銆?}

        浠庝互涓婁唬鐮佸彲浠ョ湅鍑猴紝璇诲彇鍏冪礌鏃朵笉鍔犻攣鐨勶紝姝ゆ椂閲囩敤鐨勬槸寮变竴鑷存€х瓥鐣ャ€傝幏鍙栨寚瀹氫綅缃殑鍏冪礌鍒嗕负涓ゆ锛岄鍏堣幏鍙栧埌褰撳墠list閲岄潰鐨刟rray鏁扮粍锛岃繖閲岀О涓烘楠?锛岀劧鍚庨€氳繃闅忔満璁块棶鐨勪笅鏍囨柟寮忚闂寚瀹氫綅缃殑鍏冪礌锛岃繖閲岀О涓烘楠?銆?        鍥犱负鏁翠釜杩囩▼骞舵病鏈夊姞閿侊紝杩欏氨鍙兘浼氬鑷村綋鎵ц瀹屾楠?鍚庢墽琛屾楠?鍓嶏紝鍙﹀涓€涓嚎绋婥杩涜浜嗕慨鏀规搷浣滐紝姣斿remove鎿嶄綔锛屽氨浼氳繘琛屽啓鏃舵嫹璐濆垹闄ゅ綋鍓峠et鏂规硶瑕佽闂殑鍏冪礌锛屽苟涓斾慨鏀瑰綋鍓峫ist鐨刟rray涓烘柊鏁扮粍銆傝€岃繖涔嬪悗姝ラ2 鍙兘鎵嶅紑濮嬫墽琛岋紝姝ラ2鎿嶄綔鐨勬槸绾跨▼C鍒犻櫎鍏冪礌鍓嶇殑涓€涓揩鐓ф暟缁勶紙鍥犱负姝ラ1璁゛rray鎸囧悜鐨勬槸鍘熸潵鐨勬暟缁勶級锛屾墍浠ヨ櫧鐒剁嚎绋婥宸茬粡鍒犻櫎浜唅ndex澶勭殑鍏冪礌锛屼絾鏄楠?杩樻槸杩斿洖index澶勭殑鍏冪礌锛岃繖鍏跺疄灏辨槸鍐欐椂鎷疯礉绛栫暐甯︽潵寮变竴鑷存€с€?/code>

7銆佷慨鏀规寚瀹氬厓绱狅紝鑻ュ厓绱犱笉瀛樺湪鍒欐姏鍑簄dexOutOfBoundsException銆?br/>/**

  • Replaces the element at the specified position in this list with the
  • specified element.
  • @throws IndexOutOfBoundsException {@inheritDoc}
    */
    public E set(int index, E element) {
    final ReentrantLock lock = this.lock;
    lock.lock();//鐙崰閿?br/>try {
    Object[] elements = getArray();
    E oldValue = get(elements, index); //鑾峰彇鎸囧畾浣嶇疆鐨勫厓绱?/p>

        if (oldValue != element) {
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len);
            newElements[index] = element; //鏇存柊鎸囧畾浣嶇疆涓婄殑鍏冪礌
            setArray(newElements);
        } else {
            // Not quite a no-op; ensures volatile write semantics  鍚屼竴瀵硅薄锛屽垯涓嶆洿鏂帮紝
            setArray(elements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }

    }
    濡傛灉鎸囧畾浣嶇疆鍏冪礌涓庢柊鍊间竴鏍凤紝鍒欎负浜嗕繚闅渧olatile璇箟锛岃繕鏄渶瑕侀噸鏂拌缃笅array锛岃櫧鐒禷rray鍐呭骞舵病鏈夋敼鍙?涓轰簡淇濊瘉 volatile 璇箟鏄€冭檻鍒?set 鏂规硶鏈韩搴旇鎻愪緵 volatile 鐨勮涔夛級.銆?/p>

    7銆佸垹闄ゅ厓绱?    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)
            setArray(Arrays.copyOf(elements, len - 1));
        else {
            Object[] newElements = new Object[len - 1];
                          //鍒嗕袱娆℃嫹璐濆垹闄ゅ悗鐨勬暟缁?                        //鍏堝鍒秈ndex浣嶇疆涔嬪墠鐨勫厓绱狅紝
            System.arraycopy(elements, 0, newElements, 0, index); //index鍦ㄦ澶勮〃绀鸿澶嶅埗鐨勯暱搴︽垨鍏冪礌涓暟
                            //澶嶅埗inex浣嶇疆涔嬪悗鐨勫厓绱?        System.arraycopy(elements, index + 1, newElements, index,
                             numMoved);
                            //鍏朵腑锛歴rc琛ㄧず婧愭暟缁勶紝srcPos琛ㄧず婧愭暟缁勮澶嶅埗鐨勮捣濮嬩綅缃紝desc琛ㄧず鐩爣鏁扮粍锛宭ength琛ㄧず瑕佸鍒剁殑闀垮害銆?        setArray(newElements);
        }
        return oldValue;
    } finally {
        lock.unlock(); //鎿嶄綔瀹屾垚锛岃В闄ら攣瀹?}

    }

    8銆佸急涓€鑷存€х殑杩唬鍣?/code>

    /**

  • Returns an iterator over the elements in this list in proper sequence. 杩斿洖涓€瀹氶『搴忕殑鐨勫厓绱犲垪琛紙杩唬鍣級
  • <p>The returned iterator provides锛堟彁渚涳級 a snapshot锛堝揩鐓э級 of the state of the list
  • when the iterator was constructed. No synchronization is needed while
  • traversing the iterator. The iterator does <em>NOT</em> support the
  • <tt>remove</tt> method. 澶ф鎰忔€濆氨鏄細杩斿洖鐨勮凯浠e櫒鏄痩ist鍒楄〃鐨勪竴涓揩鐓э紝鍦ㄦ暣涓凯浠g殑杩囩▼涓笉闇€瑕佸悓姝ワ紙鍔犻攣锛夛紝杩欎釜杩唬鍣ㄤ笉鏀寔remove鎿嶄綔銆?/li>
  • @return an iterator over the elements in this list in proper sequence
    */
    public Iterator<E> iterator() {
    return new COWIterator<E>(getArray(), 0);
    }

    /**

  • {@inheritDoc}
  • <p>The returned iterator provides a snapshot of the state of the list
  • when the iterator was constructed. No synchronization is needed while
  • traversing the iterator. The iterator does <em>NOT</em> support the
  • <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods. 涓嶆敮鎸乺emove/set/add绛夋搷浣?br/>*/
    public ListIterator<E> listIterator() {
    return new COWIterator<E>(getArray(), 0);
    }

    /**

  • {@inheritDoc}
  • <p>The returned iterator provides a snapshot of the state of the list
  • when the iterator was constructed. No synchronization is needed while
  • traversing the iterator. The iterator does <em>NOT</em> support the
  • <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
  • @throws IndexOutOfBoundsException {@inheritDoc}
    */
    public ListIterator<E> listIterator(final int index) {
    Object[] elements = getArray();
    int len = elements.length;
    if (index<0 || index>len)
    throw new IndexOutOfBoundsException("Index: "+index);

    return new COWIterator<E>(elements, index);

    }

    private static class COWIterator<E> implements ListIterator<E> {
    /* Snapshot of the array /array鏁扮粍鐨勪竴涓揩鐓?br/>private final Object[] snapshot;
    /* Index of element to be returned by subsequent call to next. /灏嗙敱鍚庣画璋冪敤next杩斿洖鐨勫厓绱犵殑绱㈠紩銆傚嵆鏁扮粍涓嬫爣鎴栫储寮?br/>private int cursor;

    private COWIterator(Object[] elements, int initialCursor) {
        cursor = initialCursor;
        snapshot = elements;
    }
    
    //鍒ゆ柇鏄惁鏈変笅涓厓绱?public boolean hasNext() {
        return cursor < snapshot.length;
    }
    
            ......
    //鑾峰彇褰撳墠鍏冪礌锛岀储寮曞姞1
    @SuppressWarnings("unchecked")
    public E next() {
        if (! hasNext())
            throw new NoSuchElementException();
        return (E) snapshot[cursor++];
    }
            .....

    }

    杩欓噷涓轰粈涔堣snapshot鏄痩ist鐨勫揩鐓у憿锛熸槑鏄庢槸鎸囬拡浼犻€掔殑寮曠敤锛岃€屼笉鏄嫹璐濄€傚鏋滃湪璇ョ嚎绋嬩娇鐢ㄨ繑鍥炵殑杩唬鍣ㄩ亶鍘嗗厓绱犵殑杩囩▼涓紝鍏朵粬绾跨▼娌℃湁瀵筶ist杩涜澧炲垹鏀癸紝閭d箞snapshot鏈韩灏辨槸list鐨刟rray,鍥犱负瀹冧滑鏄紩鐢ㄥ叧绯汇€?/code>

    浣嗘槸濡傛灉閬嶅巻鏈熼棿锛屾湁鍏朵粬绾跨▼瀵硅list杩涜浜嗗鍒犳敼锛岄偅涔坰napshot灏辨槸蹇収浜嗭紝鍥犱负澧炲垹鏀瑰悗list閲岄潰鐨勬暟缁勮鏂版暟缁勬浛鎹簡锛岃繖鏃跺€欒€佹暟缁勫彧鏈夎snapshot鎵€寮曠敤锛屾墍浠ヨ繖涔熷氨璇存槑鑾峰彇杩唬鍣ㄥ悗锛屼娇鐢ㄦ敼杩唬鍣ㄨ繘琛岄亶鍘嗗厓绱犳椂鍊欙紝鍏跺畠绾跨▼瀵硅list杩涜鐨勫鍒犳敼鏄笉鍙鐨勶紝
    鍥犱负瀹冧滑鎿嶄綔鐨勬槸涓や釜涓嶅悓鐨勬暟缁勶紝杩欎篃灏辨槸寮变竴鑷存€х殑杈炬垚銆?/p>

以上是关于CopyOnWriteArrayList婧愮爜闃呰的主要内容,如果未能解决你的问题,请参考以下文章

CRUD鎼爾涓や笁骞翠簡锛屾€庝箞闃呰Spring婧愮爜锛?/a>

銆婃繁搴﹀涔犱箣pytorch銆媝df+闄勪功婧愮爜

Objects婧愮爜瑙h

JDK婧愮爜鍒嗘瀽鍒濇鏁寸悊

ribbon婧愮爜 Server

AtomicInteger 婧愮爜鍒嗘瀽