java中那些类是线程安全的?
Java中各種集合(字符串類)的線程安全性!!!
?
一、概念:
- 線程安全:就是當多線程訪問時,采用了加鎖的機制;即當一個線程訪問該類的某個數(shù)據(jù)時,會對這個數(shù)據(jù)進行保護,其他線程不能對其訪問,直到該線程讀取完之后,其他線程才可以使用。防止出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)被污染的情況。
- 線程不安全:就是不提供數(shù)據(jù)訪問時的數(shù)據(jù)保護,多個線程能夠同時操作某個數(shù)據(jù),從而出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染的情況。
- 對于線程不安全的問題,一般會使用synchronized關(guān)鍵字加鎖同步控制。
- 線程安全 工作原理: jvm中有一個main memory對象,每一個線程也有自己的working memory,一個線程對于一個變量variable進行操作的時候, 都需要在自己的working memory里創(chuàng)建一個copy,操作完之后再寫入main memory。?
當多個線程操作同一個變量variable,就可能出現(xiàn)不可預(yù)知的結(jié)果。?
而用synchronized的關(guān)鍵是建立一個監(jiān)控monitor,這個monitor可以是要修改的變量,也可以是其他自己認為合適的對象(方法),然后通過給這個monitor加鎖來實現(xiàn)線程安全,每個線程在獲得這個鎖之后,要執(zhí)行完加載load到working memory 到 use && 指派assign 到 存儲store 再到 main memory的過程。才會釋放它得到的鎖。這樣就實現(xiàn)了所謂的線程安全。
?
二、線程安全(Thread-safe)的集合對象:
- Vector?
- HashTable
- StringBuffer
?
三、非線程安全的集合對象:
- ArrayList :
- LinkedList:
- HashMap:
- HashSet:
- TreeMap:
- TreeSet:
- StringBulider:
?
四、相關(guān)集合對象比較:
- Vector、ArrayList、LinkedList:?
1、Vector:?
Vector與ArrayList一樣,也是通過數(shù)組實現(xiàn)的,不同的是它支持線程的同步,即某一時刻只有一個線程能夠?qū)慥ector,避免多線程同時寫而引起的不一致性,但實現(xiàn)同步需要很高的花費,因此,訪問它比訪問ArrayList慢。?
2、ArrayList:?
a. 當操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或者中間,并需要隨機地訪問其中的元素時,使用ArrayList性能比較好。?
b. ArrayList是最常用的List實現(xiàn)類,內(nèi)部是通過數(shù)組實現(xiàn)的,它允許對元素進行快速隨機訪問。數(shù)組的缺點是每個元素之間不能有間隔,當數(shù)組大小不滿足時需要增加存儲能力,就要講已經(jīng)有數(shù)組的數(shù)據(jù)復(fù)制到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對數(shù)組進行復(fù)制、移動、代價比較高。因此,它適合隨機查找和遍歷,不適合插入和刪除。?
3、LinkedList:?
a. 當對一列數(shù)據(jù)的前面或者中間執(zhí)行添加或者刪除操作時,并且按照順序訪問其中的元素時,要使用LinkedList。?
b. LinkedList是用鏈表結(jié)構(gòu)存儲數(shù)據(jù)的,很適合數(shù)據(jù)的動態(tài)插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用于操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。
? Vector和ArrayList在使用上非常相似,都可以用來表示一組數(shù)量可變的對象應(yīng)用的集合,并且可以隨機的訪問其中的元素。
?
-
HashTable、HashMap、HashSet:?
HashTable和HashMap采用的存儲機制是一樣的,不同的是:?
1、HashMap:?
a. 采用數(shù)組方式存儲key-value構(gòu)成的Entry對象,無容量限制;?
b. 基于key hash查找Entry對象存放到數(shù)組的位置,對于hash沖突采用鏈表的方式去解決;?
c. 在插入元素時,可能會擴大數(shù)組的容量,在擴大容量時須要重新計算hash,并復(fù)制對象到新的數(shù)組中;?
d. 是非線程安全的;?
e. 遍歷使用的是Iterator迭代器;2、HashTable:?
a. 是線程安全的;?
b. 無論是key還是value都不允許有null值的存在;在HashTable中調(diào)用Put方法時,如果key為null,直接拋出NullPointerException異常;?
c. 遍歷使用的是Enumeration列舉;3、HashSet:?
a. 基于HashMap實現(xiàn),無容量限制;?
b. 是非線程安全的;?
c. 不保證數(shù)據(jù)的有序;
?
-
TreeSet、TreeMap:?
TreeSet和TreeMap都是完全基于Map來實現(xiàn)的,并且都不支持get(index)來獲取指定位置的元素,需要遍歷來獲取。另外,TreeSet還提供了一些排序方面的支持,例如傳入Comparator實現(xiàn)、descendingSet以及descendingIterator等。?
1、TreeSet:?
a. 基于TreeMap實現(xiàn)的,支持排序;?
b. 是非線程安全的;2、TreeMap:?
a. 典型的基于紅黑樹的Map實現(xiàn),因此它要求一定要有key比較的方法,要么傳入Comparator比較器實現(xiàn),要么key對象實現(xiàn)Comparator接口;?
b. 是非線程安全的;
?
-
StringBuffer和StringBulider:?
StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數(shù)組保存字符串。
? 1、在執(zhí)行速度方面的比較:StringBuilder > StringBuffer ;?
? 2、他們都是字符串變量,是可改變的對象,每當我們用它們對字符串做操作時,實際上是在一個對象上操作的,不像String一樣創(chuàng)建一些對象進行操作,所以速度快;?
? 3、 StringBuilder:線程非安全的;?
? 4、StringBuffer:線程安全的;?
?
對于String、StringBuffer和StringBulider三者使用的總結(jié):?
1.如果要操作少量的數(shù)據(jù)用 = String?
2.單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder?
3.多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer
轉(zhuǎn)載于:https://www.cnblogs.com/qccadmin/p/10065168.html
總結(jié)
以上是生活随笔為你收集整理的java中那些类是线程安全的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python-三元运算
- 下一篇: BZOJ3879: SvT【后缀数组+单