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婧愮爜闃呰的主要内容,如果未能解决你的问题,请参考以下文章