1. 程式人生 > >集合,ArrayList,LinkedList,HashMap,LinkedHashMap,ConcurremtHashMap分別的總結,volatile 關鍵字的使用

集合,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有依賴性)

 

自己整理的,之後複習用的。如果有不對歡迎留言,我會改進的。