詳解java各種集合的線程安全
線程安全
首先要明白線程的工作原理,jvm有一個(gè)main memory,而每個(gè)線程有自己的working
memory,一個(gè)線程對(duì)一個(gè)variable進(jìn)行操作時(shí),都要在自己的working
memory里面建立一個(gè)copy,操作完之后再寫入main
memory。多個(gè)線程同時(shí)操作同一個(gè)variable,就可能會(huì)出現(xiàn)不可預(yù)知的結(jié)果。根據(jù)上面的解釋,很容易想出相應(yīng)的scenario。
而用synchronized的關(guān)鍵是建立一個(gè)monitor,這個(gè)monitor可以是要修改的variable也可以其他你認(rèn)為合適的object比如method,然后通過(guò)給這個(gè)monitor加鎖來(lái)實(shí)現(xiàn)線程安全,每個(gè)線程在獲得這個(gè)鎖之后,要執(zhí)行完load到workingmemory -> use&assign -> store到mainmemory 的過(guò)程,才會(huì)釋放它得到的鎖。這樣就實(shí)現(xiàn)了所謂的線程安全。
什么是線程安全?線程安全是怎么完成的(原理)? 線程安全就是說(shuō)多線程訪問(wèn)同一代碼,不會(huì)產(chǎn)生不確定的結(jié)果。編寫線程安全的代碼是低依靠線程同步。
java相關(guān)集合
Vector、ArrayList、LinkedList
Vector和ArrayList在使用上非常相似,都可用來(lái)表示一組數(shù)量可變的對(duì)象應(yīng)用的集合,并且可以隨機(jī)地訪問(wèn)其中的元素。
Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由于線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。
ArrayList和LinkedList區(qū)別
對(duì)于處理一列數(shù)據(jù)項(xiàng),Java提供了兩個(gè)類ArrayList和LinkedList,ArrayList的內(nèi)部實(shí)現(xiàn)是基于內(nèi)部數(shù)組Object[],所以從概念上講,它更象數(shù)組,但LinkedList的內(nèi)部實(shí)現(xiàn)是基于一組連接的記錄,所以,它更象一個(gè)鏈表結(jié)構(gòu),所以,它們?cè)谛阅苌嫌泻艽蟮牟顒e。
從上面的分析可知,在ArrayList的前面或中間插入數(shù)據(jù)時(shí),你必須將其后的所有數(shù)據(jù)相應(yīng)的后移,這樣必然要花費(fèi)較多時(shí)間,所以,當(dāng)你的操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問(wèn)其中的元素時(shí),使用ArrayList會(huì)提供比較好的性能
而訪問(wèn)鏈表中的某個(gè)元素時(shí),就必須從鏈表的一端開始沿著連接方向一個(gè)一個(gè)元素地去查找,直到找到所需的元素為止,所以,當(dāng)你的操作是在一列數(shù)據(jù)的前面或中間添加或刪除數(shù)據(jù),并且按照順序訪問(wèn)其中的元素時(shí),就應(yīng)該使用LinkedList了。
如果在編程中,1,2兩種情形交替出現(xiàn),這時(shí),你可以考慮使用List這樣的通用接口,而不用關(guān)心具體的實(shí)現(xiàn),在具體的情形下,它的性能由具體的實(shí)現(xiàn)來(lái)保證。
HashTable,HashMap,HashSet
HashTable和HashMap采用相同的存儲(chǔ)機(jī)制,二者的實(shí)現(xiàn)基本一致,不同的是:
1)、HashMap是非線程安全的,HashTable是線程安全的,內(nèi)部的方法基本都是synchronized。
2)、HashTable不允許有null值的存在。
在HashTable中調(diào)用put方法時(shí),如果key為null,直接拋出NullPointerException。其它細(xì)微的差別還有,比如初始化Entry數(shù)組的大小等等,但基本思想和HashMap一樣。
HashSet:
1、HashSet基于HashMap實(shí)現(xiàn),無(wú)容量限制。
2、HashSet是非線程安全的。
3、HashSet不保證有序。
HashMap:
1、HashMap采用數(shù)組方式存儲(chǔ)key,value構(gòu)成的Entry對(duì)象,無(wú)容量限制。
2、HashMap基于Key hash查找Entry對(duì)象存放到數(shù)組的位置,對(duì)于hash沖突采用鏈表的方式來(lái)解決。
3、HashMap在插入元素時(shí)可能會(huì)要擴(kuò)大數(shù)組的容量,在擴(kuò)大容量時(shí)須要重新計(jì)算hash,并復(fù)制對(duì)象到新的數(shù)組中。
4、HashMap是非線程安全的。
5、HashMap遍歷使用的是Iterator
HashTable
1、HashTable是線程安全的。
2、HashTable中無(wú)論是Key,還是Value都不允許為null。
3、HashTable遍歷使用的是Enumeration。
TreeSet,TreeMap
TreeSet:
1、TreeSet基于TreeMap實(shí)現(xiàn),支持排序。
2、TreeSet是非線程安全的。
從對(duì)HashSet和TreeSet的描述來(lái)看,TreeSet和HashSet一樣,也是完全基于Map來(lái)實(shí)現(xiàn)的,并且都不支持get(int)來(lái)獲取指定位置的元素(需要遍歷獲取),另外TreeSet還提供了一些排序方面的支持。例如傳入Comparator實(shí)現(xiàn)、descendingSet以及descendingIterator等。
TreeMap:
1、TreeMap是一個(gè)典型的基于紅黑樹的Map實(shí)現(xiàn),因此它要求一定要有Key比較的方法,要么傳入Comparator實(shí)現(xiàn),要么key對(duì)象實(shí)現(xiàn)Comparable接口。
2、TreeMap是非線程安全的。
總結(jié)
以上就是本文關(guān)于詳解java各種集合的線程安全的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以參閱:Java多線程ForkJoinPool實(shí)例詳解、Java線程安全與非線程安全解析、Java利用future及時(shí)獲取多線程運(yùn)行結(jié)果等,有什么問(wèn)題可以隨時(shí)留言,歡迎大家交流討論。
相關(guān)文章
Spring Security基于JWT登錄認(rèn)證的項(xiàng)目實(shí)踐
JWT被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,本文主要介紹了Spring Security基于JWT登錄認(rèn)證的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java使用POI導(dǎo)出Excel(二):多個(gè)sheet
這篇文章介紹了Java使用POI導(dǎo)出Excel的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
SpringBoot對(duì)接AWS?S3實(shí)現(xiàn)上傳和查詢
AWS?S3是亞馬遜提供的一種對(duì)象存儲(chǔ)服務(wù),旨在提供可擴(kuò)展、高可用性和安全的數(shù)據(jù)存儲(chǔ)解決方案,本文我們就來(lái)看看SpringBoot如何對(duì)接AWS?S3實(shí)現(xiàn)上傳和查詢吧2025-02-02
RestTemplate使用不當(dāng)引發(fā)的問(wèn)題及解決
這篇文章主要介紹了RestTemplate使用不當(dāng)引發(fā)的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
一篇文章學(xué)會(huì)java死鎖與CPU 100%的排查
這篇文章主要介紹了一篇文章學(xué)會(huì)java死鎖與CPU 100%的排查,文中主要介紹了Java死鎖以及服務(wù)器CPU占用率達(dá)到100%時(shí)的排查和解決方法,感興趣的朋友一起來(lái)看一看吧2021-08-08
SpringBoot實(shí)現(xiàn)自動(dòng)配置的方式詳解
Spring Boot 自動(dòng)配置 是其核心特性之一,它通過(guò)智能化的默認(rèn)配置減少了開發(fā)者的工作量,自動(dòng)配置的原理基于條件化配置和 Spring 的 @Configuration 機(jī)制,本文給大家講解了SpringBoot實(shí)現(xiàn)自動(dòng)配置的過(guò)程,需要的朋友可以參考下2025-04-04

