CopyOnWriteArrayList源碼分析

之前介紹了ArrayList,他是在單線程下使用的集合,本文介紹下他的多線程版本CopyOnWriteArrayList。

首先來(lái)看實(shí)例變量

lock是后續(xù)add等操作需要的鎖對(duì)象,array則為存放元素的

容器。這里注意array為volatile類型,這意味著每次讀取array時(shí)不需要進(jìn)行加鎖操作,讀取的是主存中最新的值。

所以get操作就比較簡(jiǎn)單了,就是直接獲取數(shù)組中對(duì)應(yīng)的下標(biāo)元素。

接下來(lái)看set操作,set操作需要改變數(shù)組,所以這時(shí)就需要加鎖了

可以看到,他對(duì)整個(gè)操作進(jìn)行了加鎖處理防止并發(fā)問(wèn)題。由圖可知,每次進(jìn)行替換的時(shí)候都會(huì)重新copy一個(gè)新的數(shù)組,并調(diào)用setArray將其賦值給實(shí)例變量。這也是CopyOnWrite名稱的由來(lái),即寫時(shí)復(fù)制。

其他操作諸如add,remove等都是一樣的思路,代碼就不貼出來(lái)了。

CopyOnWriteArrayList的doc文檔上有說(shuō),所有可變操作通過(guò)生成數(shù)組的副本來(lái)實(shí)現(xiàn),這樣做誠(chéng)然代價(jià)比較高,而當(dāng)讀取操作的行為發(fā)生頻率遠(yuǎn)高于可變操作時(shí),這種形式效率就比較高了。所以CopyOnWriteArrayList的使用場(chǎng)景是讀多寫少。

寫時(shí)復(fù)制的方式解決了多線程同時(shí)讀取寫入讀取不需要加鎖的問(wèn)題,然而這會(huì)引發(fā)其他的問(wèn)題,因?yàn)閷憰r(shí)內(nèi)存中數(shù)組可能有倆份,一份舊數(shù)組,一份新數(shù)組,寫入時(shí)array變量引用還未指向新數(shù)組時(shí),另一線程進(jìn)行讀操作,這時(shí)讀取操作使用的是舊數(shù)組,讀取到的可能就是舊數(shù)據(jù),導(dǎo)致數(shù)據(jù)的不一致,所以CopyOnWriteArrayList只能保證最終數(shù)據(jù)一致性,而非實(shí)時(shí)一致性,使用的時(shí)候需要注意。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容