一、同步類容器
同步類容器都是線程安全的,但在某些場景下可能需要加鎖來保護(hù)復(fù)合操作。復(fù)合操作如:迭代(反復(fù)訪問元素,遍歷完容器中所有的元素)、跳轉(zhuǎn)(根據(jù)指定的順序找到當(dāng)前元素的下一個元素)、以及條件運算。這些復(fù)合操作在多線程并發(fā)地修改容器時,可能會表現(xiàn)出意外的行為,最經(jīng)典的便是ConcurrentModificationException
,原因是當(dāng)容器迭代的過程中,被并發(fā)的修改了內(nèi)容這是由于早期迭代器設(shè)計的時候未考慮并發(fā)修改的問題。
同步類容器:如古老的Vector
、HashTable
,這些容器的同步功能其實都是有JDK的Collections.synchronized***
等工廠方法去創(chuàng)建實現(xiàn)的。其底層的機(jī)會無非就是用傳統(tǒng)的synchronized
關(guān)鍵字對每個公用的方法都進(jìn)行同步,使得每次只能有一個線程訪問容器的狀態(tài)。這很明顯不能滿足我們今天互聯(lián)網(wǎng)時代高并發(fā)的需求,保證線程安全的同時,必須要有足夠好的性能。對于單獨的并發(fā)修改,是線程安全的。
1. Vector & ArrayList
(1) Vector
的方法都是同步的(Synchronized
),是線程安全的(thread-safe
),而ArrayList
的方法不是,由于線程的同步必然要影響性能,因此,ArrayList
的性能比Vector
好。
(2) 當(dāng)Vector
或ArrayList
中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList
只增加50%的大小,這樣ArrayList
就有利于節(jié)約內(nèi)存空間。
2.Hashtable & HashMap
Hashtable
和HashMap
它們的性能方面的比較類似 Vector
和ArrayList
,比如Hashtable
的方法是同步的,而HashMap
的不是。
3. ArrayList & LinkedList
ArrayList
的內(nèi)部實現(xiàn)是基于內(nèi)部數(shù)組Object[]
,所以從概念上講,它更象數(shù)組,但LinkedList
的內(nèi)部實現(xiàn)是基于一組連接的記錄,所以,它更象一個鏈表結(jié)構(gòu),所以,它們在性能上有很大的差別:
(1)從上面的分析可知,在ArrayList
的前面或中間插入數(shù)據(jù)時,你必須將其后的所有數(shù)據(jù)相應(yīng)的后移,這樣必然要花費較多時間,所以,當(dāng)你的操作是在一列 數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問其中的元素時,使用ArrayList
會提供比較好的性能;
(2)而訪問鏈表中的某個元素時,就必須從鏈表的一端開始沿著連接方向一個一個元素地去查找,直到找到所需的元素為止,所以,當(dāng)你的操作是在一列數(shù)據(jù)的前面或中 間添加或刪除數(shù)據(jù),并且按照順序訪問其中的元素時,就應(yīng)該使用LinkedList
了。
4. 配置集合類的初始大小
在Java集合框架中的大部分類的大小是可以隨著元素個數(shù)的增加而相應(yīng)的增加的,我們似乎不用關(guān)心它的初始大小,但如果我們考慮類的性能問題時,就一定要考慮盡可能地設(shè)置好集合對象的初始大小,這將大大提高代碼的性能。 比如,Hashtable
缺省的初始大小為101,載入因子為0.75,即如果其中的元素個數(shù)超過75個,它就必須增加大小并重新組織元素,所以,如果你 知道在創(chuàng)建一個新的Hashtable
對象時就知道元素的確切數(shù)目如為110,那么,就應(yīng)將其初始大小設(shè)為110/0.75=148,這樣,就可以避免重 新組織內(nèi)存并增加大小。Mapmap = Collections.synchronizedMap(new HashMap());
可實現(xiàn)線程安全
二、并發(fā)類容器:
jdk1.5以后提供了多種并發(fā)類容器來替代同步類容器從而改善性能。同步類容器的狀態(tài)都是串行化的。他們雖然實現(xiàn)了線程安全,但是嚴(yán)重降低了并發(fā)性,在多線程環(huán)境時,嚴(yán)重降低了應(yīng)用程序的吞吐量。
并發(fā)類容器是專門針對并發(fā)設(shè)計的,使用ConcurrentHashMap
來代替給予散列的傳統(tǒng)的HashTable
,而且在ConcurrentHashMap
中,添加了一些常見復(fù)合操作的支持。
使用了CopyOnWriteArrayList
代替Vector
,并發(fā)的CopyOnWriteArraySet
,以及并發(fā)的Queue
,ConcurrentLinkedQueue
和LinkedBlockingQueue
,前者是高性能隊列,后者是阻塞形式的隊列,具體還有ArrayBlockingQueue
、PriorityBlockingQueue
、SynchronousQueue
等。