集合,ArrayList,LinkedList,HashMap,LinkedHashMap,ConcurremtHashMap分別的總結,volatile 關鍵字的使用
1 集合
1.1 List
1.1.1 ArrayList
動態陣列
實現list介面,非同步
有序的排列
最好設定length長度,不然會引起記憶體洩露
查詢很快,刪除新增較慢(因為需要移動資料)
1.1.2 linkedList
雙向列表結構
Fail-fast
(fail-fast 迭代器,這意味著它們假設執行緒在集合內容中進行迭代時,集合不會更改它的內容。如果 fail-fast 迭代器檢測到在迭代過程中進行了更改操作,那麼它會丟擲 ConcurrentModificationException)
從兩邊插入,查詢較慢,新增刪除較快(因為是指標移動)
不容易記憶體洩露
1.2 Map
1.2.1 HashMap
非執行緒安全,單鏈表結構,容易造成死鎖
鍵值對
非同步的
無序的,
get、set較快
1.2.2 linkedHashMap
有序的雙鏈表結構,可以根據訪問次數進行排序
1.2.3 ConcurremtHashMap
訪問會走兩步,一步是hash查詢到segments,然後到HashEntry
ConcurremtHashMap在segments上加鎖,HashTable不同的是,所有的key競爭一個鎖
可以適用於高併發,多執行緒
執行緒安全
1),ConcurremtHashMap的鎖分段技術
通過使用段(Segment)將ConcurrentHashMap劃分為不同的部分,ConcurrentHashMap就可以使用不同的鎖來控制對雜湊表的不同部分的修改,從而允許多個修改操作併發進行, 這正是ConcurrentHashMap鎖分段技術的核心內涵。
2),ConcurrentHashMap的讀是否要加鎖,為什麼
不需要加鎖
第一:使用volatile關鍵字會強制將修改的值立即寫入主存;
第二:使用volatile關鍵字的話,當執行緒2進行修改時,會導致執行緒1的工作記憶體中快取變數的快取行無效(反映到硬體層的話,就是CPU的L1或者L2快取中對應的快取行無效);
第三:由於執行緒1的工作記憶體中快取變數的快取行無效,所以執行緒1再次讀取變數的值時會去主存讀取。總結
ConcurrentHashMap的get操作全程不需要加鎖,這也是它比其他併發集合比如hashtable、用Collections.synchronizedMap()包裝的hashmap;安全效率高的原因之一。
get操作全程不需要加鎖是因為Node的成員val是用volatile修飾的和陣列用volatile修飾沒有關係。
陣列用volatile修飾主要是保證在陣列擴容的時候保證可見性。
3),ConcurrentHashMap的迭代器是強一致性的迭代器還是弱一致性的迭代器
弱一致迭代器
1.2.4 volatile 關鍵字
一個被共享的變數被volatile修飾之後便具備了兩層含義
1),不同的執行緒對這個變數進行操作時的可見性,即一個執行緒修改了這個可變變數,這個新值對其他執行緒來說是立即更新的
2),禁止處理器進行性重排序
3),但是不能保證原子性
1.2.5 三種特性
1),原子性(適用於高併發所考慮的事情)
2),可見性(適用於多個執行緒修改同一個變數時,可能會考慮的事情)
3),有序性
Int a = 0; T1
Int b = 1; T2
A=a+1; T3
B = a*a; T41
(處理器會進行重新排序, T4一定在T3後面執行,因為T4對T3有依賴性)
自己整理的,之後複習用的。如果有不對歡迎留言,我會改進的。