集合的線程安全性

Vector、ArrayList、LinkedList

Vector和ArrayList在使用上很是類似,均可用來表示一組數量可變的對象應用的集合,而且能夠隨機地訪問其中的元素。 
Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,因爲線程的同步必然要影響性能,所以,ArrayList的性能比Vector好。 LinkedList也不是線程安全的。 java

ArrayList和LinkedList區別
對於處理一列數據項,Java提供了兩個類ArrayList和LinkedList,ArrayList的內部實現是基於內部數組Object[],因此從概念上講,它更象數組,但LinkedList的內部實現是基於一組鏈接的記錄,因此,它更象一個鏈表結構,因此,它們在性能上有很大的差異。  
從上面的分析可知,在ArrayList的前面或中間插入數據時,你必須將其後的全部數據相應的後移,這樣必然要花費較多時間,因此,當你的操做是在一列數據的後面添加數據而不是在前面或中間,而且須要隨機地訪問其中的元素時,使用ArrayList會提供比較好的性能  
而訪問鏈表中的某個元素時,就必須從鏈表的一端開始沿着鏈接方向一個一個元素地去查找,直到找到所需的元素爲止,因此,當你的操做是在一列數據的前面或中間添加或刪除數據,而且按照順序訪問其中的元素時,就應該使用LinkedList了。  
若是在編程中,1,2兩種情形交替出現,這時,你能夠考慮使用List這樣的通用接口,而不用關心具體的實現,在具體的情形下,它的性能由具體的實現來保證。編程

HashTable,HashMap,HashSet

HashTable和HashMap採用相同的存儲機制,兩者的實現基本一致,不一樣的是:
1)、HashMap是非線程安全的,HashTable是線程安全的,內部的方法基本都是synchronized。
2)、HashTable不容許有null值的存在。
在HashTable中調用put方法時,若是key爲null,直接拋出NullPointerException。其它細微的差異還有,好比初始化Entry數組的大小等等,但基本思想和HashMap同樣。數組

HashSet:
一、HashSet基於HashMap實現,無容量限制。
二、HashSet是非線程安全的。
三、HashSet不保證有序。

HashMap:
一、HashMap採用數組方式存儲key,value構成的Entry對象,無容量限制。
二、HashMap基於Key hash查找Entry對象存放到數組的位置,對於hash衝突採用鏈表的方式來解決。
三、HashMap在插入元素時可能會要擴大數組的容量,在擴大容量時需要從新計算hash,並複製對象到新的數組中。
四、HashMap是非線程安全的。
五、HashMap遍歷使用的是Iterator

HashTable
一、HashTable是線程安全的。
二、HashTable中不管是Key,仍是Value都不容許爲null。
三、HashTable遍歷使用的是Enumeration。安全

TreeSet,TreeMap

TreeSet:
 一、TreeSet基於TreeMap實現,支持排序。
 二、TreeSet是非線程安全的。

從對HashSet和TreeSet的描述來看,TreeSet和HashSet同樣,也是徹底基於Map來實現的,而且都不支持get(int)來獲取指定位置的元素(須要遍歷獲取),另外TreeSet還提供了一些排序方面的支持。例如傳入Comparator實現、descendingSet以及descendingIterator等。

TreeMap:
一、TreeMap是一個典型的基於紅黑樹的Map實現,所以它要求必定要有Key比較的方法,要麼傳入Comparator實現,要麼key對象實現Comparable接口。
二、TreeMap是非線程安全的。併發

總結

Vector,HashTable是線程安全的。性能

ArrayList,LinkedList,HashMap,TreeMap,HashSet,TreeSet都不是線程安全的。spa

java.util.concurrent包提供了映射表、有序集和隊列的高效實現,容許併發訪問:ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue線程

固然對於上述線程不安全的集合也可使用同步包裝器Collections.synchronizedList(List<T> list)等,使得集合的方法使用鎖加以保護,提供了線程安全的訪問。若是在另外一個線程可能進行修改時要對集合進行迭代,仍然須要使用「客戶端」鎖定。code

相關文章
相關標籤/搜索