提到執行緒安全我們應該第一時間想到鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用,所以通過加鎖我們就可以保證乙個執行緒的安全性,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資源的效果,不要讓...