在併發環境下
,我們經常使用的集合類(list、map、set)其實都是不安全的!
list
list在單執行緒的情況下是安全的,但是多執行緒的情況下是不安全的,我們來看兩段**:
單執行緒
多執行緒
通過以上兩段**,我們可以看到,在多執行緒情況下會報concurrentmodificationexception(併發修改)
異常,那我們如何去保證在多執行緒的情況下list的安全了,有以下三中方法:
使用vector,我們都知道vector是執行緒安全的。
2.利用collections類下的方法synchronizedlist
,將其變為安全的集合類。
3. 使用copyonwritearraylist。
三種方式比較:
vector
我們首先看下vector和arraylist的原始碼,
通過原始碼我們知道vector在jdk1.0的時候就已經有了,而arraylist是在jdk1.2才有的,不知道大家有沒有想過這樣乙個問題,vector既然已經處理了執行緒不安全的問題,為什麼還有新增乙個不安全的arraylist呢?其實是有原因的,雖然實現了list介面,底層都是陣列,但是vector的效能卻比arraylist低。所以我們一般的話不採用vector。
synchronizelist
通過原始碼分析,它是通過給自己本身暴力加鎖而實現執行緒安全的,所以效率也比較低下,但是相對於vector高點。
copyonwritearraylist
copyonwritearraylist其實利用了計算機領域的乙個cow思想,多個呼叫者,想呼叫相同的資源,改變指標指向;在多執行緒下如果只是去讀,就不會產生鎖! 假如你是去寫,就需要拷貝乙份都自己**,修改完畢後,再替換指標!這樣寫的話保證資料的安全,效率也高,推薦使用!
還是首先來一段**:
我們可以看到,hashmap是不安全的,解決方案就是使用hashtablehe和concurrenthashmap。hashtable效率低下,不建議使用!
set的底層是hashmap,hashmap是不安全的,所以set自然也是執行緒不安全的。解決方案就是synchronizedset和copyonwriteset。
JUC 集合不安全類
juc arraylist底層是乙個陣列,預設大小10,超過就擴容,擴原值的一半10 5 15 執行緒不安全,因為add方法沒有加鎖。不安全案例 public class containernotsafedemo string.valueof i start 參考 add原始碼 public boo...
不安全的集合類Set
小知識 hashset的底層是hashmap,拋棄了value只用了key 示例 public class listdemo start 休眠等待執行緒跑完 thread.sleep 100 輸出集合數量 system.out.println list的數量為 list.size 示例結果 使用co...
不安全的集合類Map
示例 public class listdemo start 休眠等待執行緒跑完 thread.sleep 100 輸出集合數量 system.out.println map的數量為 map.size 示例結果 使用collections.synchronizedmap newhashmap 將ha...