CopyOnWriteArrayList學習筆記

2021-10-20 17:57:16 字數 1835 閱讀 4305

前言

並發包中的併發list只有copyonwritearraylist。copyonarraylist是乙個執行緒安全的arraylist,對其進行修改的操作都是在底層的乙個複製的陣列上進行的,也就是使用了寫時複製策略。

copyonwritearraylist原始碼解析

初始化public copyonwritearraylist()

無參建構函式內部建立了乙個大小為0的object陣列作為array的初始值。然後看下有參建構函式:

// 如果是普通的 list ,都會重新拷貝乙份,不會影響原來的 list

public copyonwritearraylist(collection<? extends e> c)

setarray(elements);

}//建立list,其內部元素是入參tocopyin的副本

public copyonwritearraylist(e tocopyin)

新增元素

尾部新增

public boolean add(e e) finally

}從上get到:

呼叫add方法只有乙個執行緒會獲取到該鎖,其它執行緒會被阻塞掛起直到鎖被釋放

新陣列的大小是原來陣列大小增加1,所以copyonwritearraylist是無界list

在新增元素時,首先複製了乙個快照,然後在快照上進行新增,而不是直接在原來陣列上進行

add指定位置新增元素:

public void add(int index, e element)

// index 索引位置的值是空的,直接賦值即可。

newelements[index] = element;

setarray(newelements);

} finally

}從上get到:

當插入的位置正好位於末尾時,只需要拷貝一次,當插入的位置處於中間時,此時我們會把原陣列一分為二,進行兩次拷貝操作。

刪除操作和add方法類似,這裡看下批量刪除操作:

public boolean removeall(collection<?> c)

// 拷貝新陣列,變相的刪除了不包含在 c 中的元素

if (newlen != len)

}return false;

} finally

}從上get到:

批量刪除操作並不會直接對陣列中的元素進行挨個刪除,而是先將陣列中的值進行迴圈判斷,把我們不需要刪除的陣列放到臨時陣列中,最後臨時陣列中的資料就是我們不需要刪除的資料。這樣提公升了效能

迭代器的弱一致性

弱一致性是指返回迭代器後,其它執行緒對list的增刪改對迭代器是不可見的。

public iteratoriterator()

static final class cowiteratorimplements listiterator

public boolean hasnext()

public boolean hasprevious()

@suppresswarnings("unchecked")

public e next()

}如果沒有其它執行緒對list進行增刪改,那麼snapshot本身就是list的array,因為他們是引用關係。但是如果在遍歷期間其它執行緒對該list進行增刪改,那麼snapshot就是快照了,因為在增刪改之後list裡面的陣列就被新陣列替換了,它們操作的是兩個不同的陣列,這就是弱一致性。

總結copyonwritearraylist僅適用於寫操作非常少的場景,而且能夠容忍讀寫的短暫不一致

copyonwritearraylist迭代器是唯讀的,不支援增刪改。因為迭代器遍歷的僅僅是乙個快照,而對快照行增刪改是沒有意義的

CopyOnWriteArrayList原始碼解讀

概述copyonwritearraylist是jdk concurrent包中提供的乙個非阻塞型的,執行緒安全的list實現。copyonwritearraylist在進行資料修改時,都不會對資料進行鎖定,每次修改時,先拷貝整個陣列,然後修改其中的一些元素,完成上述操作後,替換整個陣列的指標。對co...

CopyOnWriteArrayList 原始碼分析

1.copyonwritearraylist 是執行緒安全的arraylist,適用於儲存的資料量不大,讀操作遠多於寫操作,對實時性要求不高的場景。copyonwritearraylist 對 讀操作不同步,對寫操作同步。在進行寫操作時,會對共享變數進行copy,在副本上進行更新,然後將更新好的副本...

CopyOnWriteArrayList原始碼分析

原始碼基於1.8.0 112 copyonwritearraylist也是通過陣列來儲存元素,閱讀過之前的arraylist的話這邊應該很容易理解 原理 copyonwritearraylist內部通過陣列來儲存資料,每次修改list都會產生乙個新的陣列,然後複製原始資料。修改方法都通過內部的而乙個...