|
線程安全數組 |
非線程安全安全 |
Collection多線程 |
Vectoride |
ArrayList、LinkedListui |
|
HashSet、TreeSetspa |
|
Map.net |
HashTable線程 |
HashMap、TreeMapcode |
字符串對象 |
StringBuffer |
StringBuilder |
1、ArrayList和vector區別
Vector和ArrayList間惟一的區別就是Vector每一個方法都自帶同步機制。
例:好比我要往集合裏面加一個元素,又要保證多個線程不會同時調用同一個對象的add()方法,ArrayList裏面就要這樣寫:
ArrayList<String> list = new ArrayList<>(); synchronized (list) { list.add("233"); }
而Vector裏面只要這樣寫就好了:
Vector<String> list = new Vector<>(); list.add("233");
由於ArrayList的add方法是這樣定義的:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
而Vector的add方法是這樣定義的:
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; }
2、HashTable、HashMap、HashSet:
HashTable和HashMap採用的存儲機制是同樣的,不一樣的是:
一、HashMap:
a. 非線程安全;
b. 採用數組方式存儲key-value構成的Entry對象,key容許爲null,無容量限制;
c. 遍歷使用的是Iterator迭代器;
二、HashTable:
a. 線程安全; (對方法加上synchronized)
b. 不管是key仍是value都不容許有null值的存在;在HashTable中調用Put方法時,若是key爲null,直接拋出NullPointerException異常;
c. 遍歷使用的是Enumeration列舉;
三、HashSet:
a. 非線程安全
b. 底層經過HashMap實現,無容量限制;
c. 不保證數據的有序;
在HashSet中,元素都存到HashMap鍵值對的Key上面,而Value是統一的值private static final Object PRESENT = new Object();,(定義一個虛擬的Object對象做爲HashMap的value,將此對象定義爲static final。)
HashSet的add(E e)底層實現調用hashmap的put(E e),將該元素做爲key放入HashMap。
因爲HashMap的put()方法添加key-value對時,當新放入HashMap的Entry中key與集合中原有Entry的key相同(hashCode()返回值相等,經過equals比較也返回true), 新添加的Entry的value會將覆蓋原來Entry的value,但key不會有任何改變, 所以若是向HashSet中添加一個已經存在的元素時,新添加的集合元素將不會被放入HashMap中, 原來的元素也不會有任何改變,這也就知足了Set中元素不重複的特性。
HashSet參考:http://zhangshixi.iteye.com/blog/673143
3、TreeSet、TreeMap:
TreeSet和TreeMap都是徹底基於Map來實現的,而且都不支持get(index)來獲取指定位置的元素,須要遍從來獲取。另外,TreeSet還提供了一些排序方面的支持,例如傳入Comparator實現、descendingSet以及descendingIterator等。
一、TreeSet:
a. 非線程安全
b. 底層基於TreeMap實現,支持排序;
二、TreeMap:
a. 非線程安全;
b. 典型的基於紅黑樹的Map實現,所以它要求必定要有key比較的方法,要麼傳入Comparator比較器實現,要麼key對象實現Comparator接口;
與hashmap相比,treemap內部的元素都是排序的,當須要查找某些元素以及順序輸出元素的時候佔優點。所以,TreeMap是一個內部元素排序版的HashMap
4、StringBuffer和StringBulider:
StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數組保存字符串。
它們是字符串變量,是可改變的對象,每當咱們用它們對字符串作操做時,其實是在一個對象上操做的,不像String同樣建立一些對象進行操做,因此速度就快了;
一、在執行速度方面的比較:StringBuilder > StringBuffer ;
二、StringBuilder:非線程安全;
三、StringBuffer:線程安全; (對方法加上synchronized)
對於String、StringBuffer和StringBulider三者使用的總結:
1.若是要操做少許的數據:String
2.單線程操做字符串緩衝區下操做大量數據:StringBuilder
3.多線程操做字符串緩衝區下操做大量數據:StringBuffer
非線程安全!=不安全
雖然ArrayList是線程不安全的,但不表明在多線程下不能使用ArrayList,只能使用Vector。
非線程安全並非多線程環境下就不能使用。線程安全問題在於:多線程操做同一個對象。注意是同一個對象。好比最上面那個模擬,就是在主線程中new的一個ArrayList而後多個線程操做同一個ArrayList對象。
若是是每一個線程中new一個ArrayList,而這個ArrayList只在這一個線程中使用,那麼確定是沒問題的。
參考:
http://www.javashuo.com/article/p-twxhxepi-nh.html
https://www.zhihu.com/question/49855966