首頁  >  文章  >  Java  >  Java各種集合的線程安全分析

Java各種集合的線程安全分析

黄舟
黄舟原創
2017-10-12 10:05:521195瀏覽

這篇文章主要介紹了詳解java各種集合的線程安全,小編覺得挺不錯的,這裡分享給大家,供需要的朋友參考。

執行緒安全性

首先要明白執行緒的工作原理,jvm有一個main memory,而每個執行緒有自己的working

memory,當一個執行緒對一個variable進行操作時,都要在自己的working

#memory裡面建立一個copy,操作完之後再寫入main

#memory。多個執行緒同時操作同一個variable,就可能會出現不可預測的結果。根據上面的解釋,很容易想出相應的scenario。

而用synchronized的關鍵是建立一個monitor,這個monitor可以是要修改的variable也可以其他你認為合適的object比如method,然後透過給這個monitor加鎖來實現線程安全,每個執行緒在取得這個鎖定之後,要執行完load到workingmemory -> use&assign -> store到mainmemory 的過程,才會釋放它得到的鎖。這樣就實現了所謂的線程安全。

什麼是線程安全?線程安全是怎麼完成的(原理)? 線程安全就是說多線程訪問同一程式碼,不會產生不確定的結果。編寫線程安全的程式碼是低依靠線程同步。

java相關集合

Vector、ArrayList、LinkedList

Vector和ArrayList在使用上非常相似,都可用來表示一組數量可變的物件應用的集合,並且可以隨機地存取其中的元素。

   Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由於線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。

    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:

1、HashSet是基於HashMap實現,無容量限制。

2、HashSet是非執行緒安全的。

3、HashSet不保證有序。

HashMap:

1、HashMap採用陣列方式儲存key,value構成的Entry對象,無容量限制。

2、HashMap基於Key hash查找Entry物件存放到陣列的位置,對於hash衝突採用鍊錶的方式來解決。

3、HashMap在插入元素時可能會要擴大陣列的容量,在擴大容量時必須重新計算hash,並複製物件到新的陣列中。

4、HashMap是非線程安全的。

5、HashMap遍歷使用的是Iterator

#HashTable

1、HashTable是執行緒安全的。

2、HashTable中無論是Key,或是​​Value都不允許為null。

3、HashTable遍歷使用的是Enumeration。

TreeSet,TreeMap

TreeSet:

1、TreeSet基於TreeMap實現,支援排序。

2、TreeSet是非執行緒安全的。

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

TreeMap:

1、TreeMap是典型的基於紅黑樹的Map實現,因此它要求一定要有Key比較的方法,要嘛傳入Comparator實現,要嘛key物件實作Comparable介面。

2、TreeMap是非執行緒安全的。

總結

#

以上是Java各種集合的線程安全分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn