private transient volatile Object[] array;
public CopyOnWriteArrayListAnalysis() {
setArray(new Object[0]);
}
final void setArray(Object[] a) {
array = a;
}
public CopyOnWriteArrayListAnalysis(E[] toCopyIn) {
//工具函數Arrays.copyOf表示複製一個第二參數的長度,內容爲第一個參數的數組,而且返回的數組類型是第三個參數
setArray(Arrays.copyOf(toCopyIn, toCopyIn.length,Object[].class));
}
public CopyOnWriteArrayListAnalysis(Collection<? extends E> c) {
Object[] elements;
if(c.getClass() == CopyOnWriteArrayListAnalysis.class) {
elements = ((CopyOnWriteArrayListAnanlysis)c).getArray();
}else {
elements = c.toArray();
//下面這條語句是用來判斷若是沒有返回一個Object[].class的狀況
if(elements.getClass() != Object[].class) {
elements = Arrays.copyOf(elements,elements.length,Object[].class);
}
}
}
final Object[] getArray() {
return array;
}
public boolean add(E element) {
final ReentrantLock lock = this.lock; // 獲取該實例的獨佔鎖
lock.lock();
try {
Object[] elements = getArray(); // 獲取內部存儲的數組,注意這時候仍是原來的數組,
// 只不過是使用一個新的引用來指向它的地址
int len = elements.length; // 獲取數組的長度
Object[] newElements = Arrays.copyOf(elements,len+1);
// 使用Arrays工具類,建立一個新的數組,將前面的元素全都複製進去,而且留出一個位置
newElements[len] = element;
// 使用這個新數組來代替原來的數組
setArray(newElements);
}finally {
lock.unlock();
}
}
❝注意點:(1)因爲使用了獨佔鎖,因此同一時間只能由一個線程來進行add操做,保證了原子性;(2)add操做是建立一個新的數組,不是在原來的數組上進行操做的 ,而且該List輸一個無界Listgit
❞
public E get(int index) {
return get(getArray(),index);
}
public E get(Object[] a,int index) {
return (E)a[index];
}
public E set(int index ,E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] a = getArray();
E oldValue = a[index];
if(oldValue != element) {
int len = a.length;
Object[] newElements = Arrays.copyOf(a, len);
newElements[index] = element;
setArray(newElements);
}else {
setArray(a);
}
}finally{
lock.unlock();
}
}
public E remove(int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
int removeRemain = len - (index + 1); // 這個整數表明要遷移的剩餘元素個數
if(removeRemain == 0) {
setArray(Arrays.copyOf(elements, len-1));//除了最後一個所有都copy過去
}else {
Object[] newElements = new Object[len-1];
System.arraycopy(elements,0,newElements,0,index);
System.arraycopy(elements,index+1,newElements,index,removeRemain);
// 這裏咱們學習一個函數System.arraycopy
// 第一個參數表明從哪裏複製,第二個參數表明從第幾個索引開始
// 第三個參數表明複製到哪一個數組中,從第幾個開始,複製幾個到新數組
setArray(newElements);
}
}finally {
lock.unlock();
}
}
public Iterator<E> iterator(){
return new COWIteratro<E>(getArray(),0);
}
static final class COWIterator<E> implements ListIterator<E> {
// array的快照版本
private final Object[] snapshot;
private int cursor;
private COWIterator(Object[] elements,int initialCursor) {
cursor = initialCursor;
snapshot = elements;
}
public boolean hasNext() {
return cursor < snapshot.length;
}
public E next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
return <E>snapshot[cursor++];
}
}
https://github.com/ruigege66/ConcurrentJava