ArrayList 為什麼執行緒不安全

2021-10-24 20:15:49 字數 1012 閱讀 7348

我們先來看看 arraylist 的 add 操作原始碼。

public boolean add

(e e)

arraylist 的不安全主要體現在兩個方面。

其一:

elementdata[size++

]= e;

不是乙個原子操作,是分兩步執行的。

elementdata[size]

= e;

size++

;

單執行緒執行這段**完全沒問題,可是到多執行緒環境下可能就有問題了。可能乙個執行緒會覆蓋另乙個執行緒的值。

列表為空 size = 0。

執行緒 a 執行完 elementdata[size] = e;之後掛起。a 把 「a」 放在了下標為 0 的位置。此時 size = 0。

執行緒 b 執行 elementdata[size] = e; 因為此時 size = 0,所以 b 把 「b」 放在了下標為 0 的位置,於是剛好把 a 的資料給覆蓋掉了。

執行緒 b 將 size 的值增加為 1。

執行緒 a 將 size 的值增加為 2。

這樣子,當執行緒 a 和執行緒 b 都執行完之後理想情況下應該是 「a」 在下標為 0 的位置,「b」 在標為 1 的位置。而實際情況確是下標為 0 的位置為 「b」,下標為 1 的位置啥也沒有。

其二:arraylist 預設陣列大小為 10。假設現在已經新增進去 9 個元素了,size = 9。

執行緒 a 執行完 add 函式中的ensurecapacityinternal(size + 1)掛起了。

執行緒 b 開始執行,校驗陣列容量發現不需要擴容。於是把 「b」 放在了下標為 9 的位置,且 size 自增 1。此時 size = 10。

執行緒 a 接著執行,嘗試把 「a」 放在下標為 10 的位置,因為 size = 10。但因為陣列還沒有擴容,最大的下標才為 9,所以會丟擲陣列越界異常 arrayindexoutofbound***ception

ArrayList為什麼是執行緒不安全的

提到執行緒安全我們應該第一時間想到鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用,所以通過加鎖我們就可以保證乙個執行緒的安全性,list介面下面有兩個實現,乙個是arraylist,另外乙個是vector。從原始碼的角度來看,因為ve...

ArrayList 為什麼說是執行緒不安全的

這就要從arraylist的資料結構和原始碼分析了。關鍵點是,arraylist的add的方法不是執行緒安全的。還是帶大家大致看下原始碼吧!新增元素 複寫了介面list裡面的方法,這個方法沒有任何的鎖,也沒有看到cas public boolean add e e private void ensu...

為什麼不創新

常見人抒情說,中國為什麼沒有kik呢?為什麼沒有instagram呢?語極哀怨。善,來看看 創新 需要什麼樣的土壤培植。首先人是網際網路上的第一生產力,一支能創新的團隊,必然具備以下的五個特徵。1 有創新的能力 不客氣地講,有創新能力的人不足10 的比例,即便在平均素質較高的網際網路行業,也不會超過...