Java中各類集合(字符串類)的線程安全性!!!

Java中各類集合(字符串類)的線程安全性!!!數組

 

1、概念:安全

  • 線程安全:就是當多線程訪問時,採用了加鎖的機制;即當一個線程訪問該類的某個數據時,會對這個數據進行保護,其餘線程不能對其訪問,直到該線程讀取完以後,其餘線程纔可使用。防止出現數據不一致或者數據被污染的狀況。
  • 線程不安全:就是不提供數據訪問時的數據保護,多個線程可以同時操做某個數據,從而出現數據不一致或者數據污染的狀況。
  • 對於線程不安全的問題,通常會使用synchronized關鍵字加鎖同步控制。
  • 線程安全 工做原理: jvm中有一個main memory對象,每個線程也有本身的working memory,一個線程對於一個變量variable進行操做的時候, 都須要在本身的working memory裏建立一個copy,操做完以後再寫入main memory。 
    當多個線程操做同一個變量variable,就可能出現不可預知的結果。 
    而用synchronized的關鍵是創建一個監控monitor,這個monitor能夠是要修改的變量,也能夠是其餘本身認爲合適的對象(方法),而後經過給這個monitor加鎖來實現線程安全,每一個線程在得到這個鎖以後,要執行完加載load到working memory 到 use && 指派assign 到 存儲store 再到 main memory的過程。纔會釋放它獲得的鎖。這樣就實現了所謂的線程安全。

 

2、線程安全(Thread-safe)的集合對象:多線程

  • Vector 
  • HashTable
  • StringBuffer

 

3、非線程安全的集合對象:jvm

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:

 

4、相關集合對象比較:ide

  • Vector、ArrayList、LinkedList: 
    一、Vector: 
    Vector與ArrayList同樣,也是經過數組實現的,不一樣的是它支持線程的同步,即某一時刻只有一個線程可以寫Vector,避免多線程同時寫而引發的不一致性,但實現同步須要很高的花費,所以,訪問它比訪問ArrayList慢。 
    二、ArrayList: 
    a. 當操做是在一列數據的後面添加數據而不是在前面或者中間,並須要隨機地訪問其中的元素時,使用ArrayList性能比較好。 
    b. ArrayList是最經常使用的List實現類,內部是經過數組實現的,它容許對元素進行快速隨機訪問。數組的缺點是每一個元素之間不能有間隔,當數組大小不知足時須要增長存儲能力,就要講已經有數組的數據複製到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,須要對數組進行復制、移動、代價比較高。所以,它適合隨機查找和遍歷,不適合插入和刪除。 
    三、LinkedList: 
    a. 當對一列數據的前面或者中間執行添加或者刪除操做時,而且按照順序訪問其中的元素時,要使用LinkedList。 
    b. LinkedList是用鏈表結構存儲數據的,很適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用於操做表頭和表尾元素,能夠看成堆棧、隊列和雙向隊列使用。

    Vector和ArrayList在使用上很是類似,均可以用來表示一組數量可變的對象應用的集合,而且能夠隨機的訪問其中的元素。性能

 

  • HashTable、HashMap、HashSet: 
    HashTable和HashMap採用的存儲機制是同樣的,不一樣的是: 
    一、HashMap: 
    a. 採用數組方式存儲key-value構成的Entry對象,無容量限制; 
    b. 基於key hash查找Entry對象存放到數組的位置,對於hash衝突採用鏈表的方式去解決; 
    c. 在插入元素時,可能會擴大數組的容量,在擴大容量時需要從新計算hash,並複製對象到新的數組中; 
    d. 是非線程安全的; 
    e. 遍歷使用的是Iterator迭代器;ui

    二、HashTable: 
    a. 是線程安全的; 
    b. 不管是key仍是value都不容許有null值的存在;在HashTable中調用Put方法時,若是key爲null,直接拋出NullPointerException異常; 
    c. 遍歷使用的是Enumeration列舉;spa

    三、HashSet: 
    a. 基於HashMap實現,無容量限制; 
    b. 是非線程安全的; 
    c. 不保證數據的有序;線程

 

  • TreeSet、TreeMap: 
    TreeSet和TreeMap都是徹底基於Map來實現的,而且都不支持get(index)來獲取指定位置的元素,須要遍從來獲取。另外,TreeSet還提供了一些排序方面的支持,例如傳入Comparator實現、descendingSet以及descendingIterator等。 
    一、TreeSet: 
    a. 基於TreeMap實現的,支持排序; 
    b. 是非線程安全的;對象

    二、TreeMap: 
    a. 典型的基於紅黑樹的Map實現,所以它要求必定要有key比較的方法,要麼傳入Comparator比較器實現,要麼key對象實現Comparator接口; 
    b. 是非線程安全的;

 

  • StringBuffer和StringBulider: 
    StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數組保存字符串。

    一、在執行速度方面的比較:StringBuilder > StringBuffer ; 
    二、他們都是字符串變量,是可改變的對象,每當咱們用它們對字符串作操做時,其實是在一個對象上操做的,不像String同樣建立一些對象進行操做,因此速度快; 
    三、 StringBuilder:線程非安全的; 
    四、StringBuffer:線程安全的; 


  
  對於String、StringBuffer和StringBulider三者使用的總結: 
   1.若是要操做少許的數據用 = String 
   2.單線程操做字符串緩衝區 下操做大量數據 = StringBuilder 
   3.多線程操做字符串緩衝區 下操做大量數據 = StringBuffer

相關文章
相關標籤/搜索