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

2021-09-26 22:40:33 字數 1086 閱讀 2620

提到執行緒安全我們應該第一時間想到鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用,所以通過加鎖我們就可以保證乙個執行緒的安全性,list介面下面有兩個實現,乙個是arraylist,另外乙個是vector。 從原始碼的角度來看,因為vector的方法前加了,synchronized 關鍵字,也就是同步的意思,sun公司希望vector是執行緒安全的,而希望arraylist是高效的。

在多個執行緒進行add操作時可能會導致elementdata陣列越界。具體邏輯如下:

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

案例分析

public static void main(string args) throws interruptedexception  catch (interruptedexception e) }}

}).start();

// 執行緒b將1000-2000新增到列表

new thread(new runnable() catch (interruptedexception e)

}} }).start();

thread.sleep(1000);

// 列印所有結果

for (int i = 0; i < list.size(); i++)

}

測試結果:

可以看到第11個元素的值為null,陣列越界

ArrayList 為什麼執行緒不安全

我們先來看看 arraylist 的 add 操作原始碼。public boolean add e e arraylist 的不安全主要體現在兩個方面。其一 elementdata size e 不是乙個原子操作,是分兩步執行的。elementdata size e size 單執行緒執行這段 完全...

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

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

Redis為什麼是單執行緒

經過多方資料收集 總結 思考,結論如下 準確地來說,該問題是 為什麼redis採用單程序單執行緒模型 我們從兩個層次去理解 第乙個層次 我們多執行緒的使用情景是io密集型,目的是為了充分利用cpu資源。也就是說當乙個執行緒io等待的時候,另乙個執行緒可以進行執行,達到充分利用cpu資源的效果,不要讓...