java中的併發集合類概述
阿新 • • 發佈:2019-02-20
一,普通集合類中執行緒安全的集合:Vector && Stack
1,Vector:
(1)預設分配初始大小為10的陣列,在構造方法中可以指定陣列初始大小和增長大小。
(2)執行緒安全主要是通過在方法中加synchronize關鍵字來實現,因此,相比於其他執行緒安全集合類,效率相對低吧。因為鎖定的是方法。
(3)檢視原始碼會發現大量使用System.arraycopy()方法。所以,集合保證插入順序,但若指定位置無序插入或刪除,會導致arraycopy()操作,
對於大量資料來說效率相對較低。
(4)提供的set(int index,Object value)方法有返回值,返回的是oldValue。get()也有synchronize關鍵字
(5)可返回迭代器。
所以,從以上特性可看出,Vector適合用於一次賦值多次讀出或資料量不大的多執行緒環境中。
2,Stack:實現先進後出的陣列。是Vector的擴充套件。是不過增加了5個關於棧操作的方法:peek(),pop(),push(),emnpty(),search().官方推薦使用
實現了Deque介面是類。 Deque<Integer> stack = new ArrayDeque<Integer>();是指雙端佇列,但這個ArrayDeque是執行緒不安全,不限
大小的,具體介面使用時再看。
二,Concurrent包中提供的執行緒安全集合()
1,ConcurrentHashMap.其主要介面方法和HashMap是差不多的。但是,ConcurrentHashMap是使用了ReentranLock(可重入鎖機制)來保證在多執行緒
環境下是執行緒安全的。
2,ConcurrentLinkedDeque:執行緒安全的雙端佇列,當然也可以當棧使用。由於是linked的,所以大小不受限制的。具體API就不多說了。
3,ConcurrentLinkedQueue:執行緒安全的佇列。
4,ConcurrentSkipListMap:基於跳錶實現的執行緒安全的MAP。除了執行緒安全的特性外,該map還接受比較器進行排序的map,演算法複雜度還是log(n)級別的。
。API中提供了一些以前不常使用的方法。以後再具體研究這個跳錶的問題。
5,ConcurrentSkipSet:基於4實現的set。
6,CopyOnWriteArrayList:以資源換取併發。通過迭代器快照的方式保證執行緒併發的訪問。
7,CopyOnWriteArraySet:基於6實現的。
三,具體看下ReentranLock(可重入鎖機制):有點複雜,以後總結。
四,下午仔細看了下ConCurrentHashMap多執行緒併發下實現的原理,就整個過程來說,實現還是比較複雜的,不僅僅是加鎖的問題,同時還應用了java
記憶體模型中的可見性原理來保證進行進行寫操作時其他程序對該程序進行讀寫的可見性。通過在hashEntry中使用final來保證所有資料的插入都會在
當前讀程序之前的,從而達到讀程序和寫程序併發。為了減小加鎖粒度,實現部分寫程序的併發,引進了Segment類,讓鎖加在Segment段中,從而
達到更多的併發,也就是傳說中的分離鎖。
最後,其實在使用鎖機制來協調多執行緒併發訪問時,減少對鎖的競爭可以有效地增加併發量,而減少對鎖的競爭最常用的方式,一個是減少請求同一個鎖的
概率,實現鎖分離。二是減少佔用鎖的時間,讓鎖的粒度達到最小。
時間關係,這個文件就到這裡。後續有時間會繼續整理下ConcurrentHashMap和ReentranLock相關機制,這對於理解多執行緒併發來說,無疑是友誼的。
1,Vector:
(1)預設分配初始大小為10的陣列,在構造方法中可以指定陣列初始大小和增長大小。
(2)執行緒安全主要是通過在方法中加synchronize關鍵字來實現,因此,相比於其他執行緒安全集合類,效率相對低吧。因為鎖定的是方法。
(3)檢視原始碼會發現大量使用System.arraycopy()方法。所以,集合保證插入順序,但若指定位置無序插入或刪除,會導致arraycopy()操作,
對於大量資料來說效率相對較低。
(4)提供的set(int index,Object value)方法有返回值,返回的是oldValue。get()也有synchronize關鍵字
(5)可返回迭代器。
所以,從以上特性可看出,Vector適合用於一次賦值多次讀出或資料量不大的多執行緒環境中。
2,Stack:實現先進後出的陣列。是Vector的擴充套件。是不過增加了5個關於棧操作的方法:peek(),pop(),push(),emnpty(),search().官方推薦使用
實現了Deque介面是類。 Deque<Integer> stack = new ArrayDeque<Integer>();是指雙端佇列,但這個ArrayDeque是執行緒不安全,不限
大小的,具體介面使用時再看。
二,Concurrent包中提供的執行緒安全集合()
1,ConcurrentHashMap.其主要介面方法和HashMap是差不多的。但是,ConcurrentHashMap是使用了ReentranLock(可重入鎖機制)來保證在多執行緒
環境下是執行緒安全的。
2,ConcurrentLinkedDeque:執行緒安全的雙端佇列,當然也可以當棧使用。由於是linked的,所以大小不受限制的。具體API就不多說了。
3,ConcurrentLinkedQueue:執行緒安全的佇列。
4,ConcurrentSkipListMap:基於跳錶實現的執行緒安全的MAP。除了執行緒安全的特性外,該map還接受比較器進行排序的map,演算法複雜度還是log(n)級別的。
。API中提供了一些以前不常使用的方法。以後再具體研究這個跳錶的問題。
5,ConcurrentSkipSet:基於4實現的set。
6,CopyOnWriteArrayList:以資源換取併發。通過迭代器快照的方式保證執行緒併發的訪問。
7,CopyOnWriteArraySet:基於6實現的。
三,具體看下ReentranLock(可重入鎖機制):有點複雜,以後總結。
四,下午仔細看了下ConCurrentHashMap多執行緒併發下實現的原理,就整個過程來說,實現還是比較複雜的,不僅僅是加鎖的問題,同時還應用了java
記憶體模型中的可見性原理來保證進行進行寫操作時其他程序對該程序進行讀寫的可見性。通過在hashEntry中使用final來保證所有資料的插入都會在
當前讀程序之前的,從而達到讀程序和寫程序併發。為了減小加鎖粒度,實現部分寫程序的併發,引進了Segment類,讓鎖加在Segment段中,從而
達到更多的併發,也就是傳說中的分離鎖。
最後,其實在使用鎖機制來協調多執行緒併發訪問時,減少對鎖的競爭可以有效地增加併發量,而減少對鎖的競爭最常用的方式,一個是減少請求同一個鎖的
概率,實現鎖分離。二是減少佔用鎖的時間,讓鎖的粒度達到最小。
時間關係,這個文件就到這裡。後續有時間會繼續整理下ConcurrentHashMap和ReentranLock相關機制,這對於理解多執行緒併發來說,無疑是友誼的。