CopyOnWriteArrayList源碼解析

CopyOnWriteArrayList源碼解析

什麼是CopyOnWriteArrayList

CopyOnWriteArrayList底層是由數組組成的一種數據結構,能夠進行動態的增刪改查html

CopyOnWriteArrayList用來幹嗎

CopyOnWriteArrayList通常用於對數據的存儲(最好針對少許數據,添加會涉及到整個數組的複製)java

源碼解析

  1. 數據的存儲
  2. 數據的操做
  3. 何時擴容
  4. 是否線程安全

帶上問題去找答案數組

數據的存儲

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    private static final long serialVersionUID = 8673264195747942595L;

    /** 用於實現add的同步操做 */
    transient final ReentrantLock lock = new ReentrantLock();

    /** volatile針對讀取時獲取最新值,同時做爲容器 */
    private volatile transient Object[] array;

數據的操做

添加
public boolean add(E e) {
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {//同步操做
		Object[] elements = getArray();
		int len = elements.length;
		Object[] newElements = Arrays.copyOf(elements, len + 1);//添加操做設計到整個數組的複製,影響性能
		newElements[len] = e;
		setArray(newElements);
		return true;
	} finally {
		lock.unlock();
	}
}
刪除
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];
			System.arraycopy(elements, 0, newElements, 0, index);
			System.arraycopy(elements, index + 1, newElements, index,
							 numMoved);
			setArray(newElements);
		}
		return oldValue;
	} finally {
		lock.unlock();
	}
}
獲取
public E get(int index) {//基於volatile獲取最新值
	return get(getArray(), index);
}

何時擴容

每次添加刪除,針對array作copy操做安全

是否線程安全

基於Lock實現併發寫入的安全,針對併發修改的讀取,修改基於copy後的新數組,讀取若是未set獲取到的仍是原數組。若是set後讀取到的就是最新的值數據結構

使用注意事項

  1. 避免CopyOnWriteArrayList過長,copy影響性能

引用

相關文章
相關標籤/搜索