概念
1. 線程安全:就是當多線程訪問時,采用了加鎖的機制赞庶;即當一個線程訪問該類的某個數(shù)據(jù)時训挡,會對這個數(shù)據(jù)進行保護,其他線程不能對其訪問歧强,直到該線程讀取完之后舍哄,其他線程才可以使用。防止出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)被污染的情況誊锭。
2.線程不安全:就是不提供數(shù)據(jù)訪問時的數(shù)據(jù)保護,多個線程能夠同時操作某個數(shù)據(jù)弥锄,從而出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染的情況丧靡。
3.對于線程不安全的問題,一般會使用synchronized關鍵字加鎖同步控制籽暇。
4. 線程安全工作原理: jvm中有一個main memory對象温治,每一個線程也有自己的working memory,一個線程對于一個變量variable進行操作的時候戒悠, 都需要在自己的working memory里創(chuàng)建一個copy,操作完之后再寫入main memory。
當多個線程操作同一個變量variable,就可能出現(xiàn)不可預知的結果摩窃。
而用synchronized的關鍵是建立一個監(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:
相關集合對象比較:
1. Vector、ArrayList、LinkedList:
1镜豹、Vector:
Vector與ArrayList一樣傲须,也是通過數(shù)組實現(xiàn)的,不同的是它支持線程的同步趟脂,即某一時刻只有一個線程能夠寫Vector泰讽,避免多線程同時寫而引起的不一致性,但實現(xiàn)同步需要很高的花費散怖,因此菇绵,訪問它比訪問ArrayList慢。
2镇眷、ArrayList:
a. 當操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或者中間咬最,并需要隨機地訪問其中的元素時,使用ArrayList性能比較好
b.ArrayList是最常用的List實現(xiàn)類欠动,內部是通過數(shù)組實現(xiàn)的永乌,它允許對元素進行快速隨機訪問。數(shù)組的缺點是每個元素之間不能有間隔具伍,當數(shù)組大小不滿足時需要增加存儲能力翅雏,就要講已經(jīng)有數(shù)組的數(shù)據(jù)復制到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時人芽,需要對數(shù)組進行復制望几、移動、代價比較高萤厅。因此橄抹,它適合隨機查找和遍歷,不適合插入和刪除惕味。
3楼誓、LinkedList:
a. 當對一列數(shù)據(jù)的前面或者中間執(zhí)行添加或者刪除操作時,并且按照順序訪問其中的元素時名挥,要使用LinkedList
b. LinkedList是用鏈表結構存儲數(shù)據(jù)的疟羹,很適合數(shù)據(jù)的動態(tài)插入和刪除,隨機訪問和遍歷速度比較慢禀倔。另外榄融,他還提供了List接口中沒有定義的方法,專門用于操作表頭和表尾元素救湖,可以當作堆棧剃袍、隊列和雙向隊列使用。
Vector和ArrayList在使用上非常相似捎谨,都可以用來表示一組數(shù)量可變的對象應用的集合民效,并且可以隨機的訪問其中的元素憔维。
ArryList和LinkedList的區(qū)別:
在處理一列數(shù)據(jù)項時,Java提供了兩個類ArrayList和LinkedList畏邢,ArrayList的內部實現(xiàn)是基于內部數(shù)組Object[]业扒,所以從概念上說它更像數(shù)組;然而LinkedList的內部實現(xiàn)是基于一組連接的記錄舒萎,所以程储,它更像一個鏈表結構;所以它們在性能上有很大的差別臂寝。
由上可知章鲤,在ArrayList的前面或者中間插入數(shù)據(jù)的時候,必須將其后的所有數(shù)據(jù)相應的后移咆贬,這樣要花費較多的時間败徊;所以,當操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或者中間掏缎,并需要隨機地訪問其中的元素時皱蹦,使用ArrayList性能比較好。
然而訪問鏈表中的某個元素的時候眷蜈,就必須從鏈表的一端開始沪哺,沿著連接的方向一個一個元素的去查找,直到找到所需的元素為止酌儒,所以辜妓,當對一列數(shù)據(jù)的前面或者中間執(zhí)行添加或者刪除操作時,并且按照順序訪問其中的元素時忌怎,要使用LinkedList嫌拣。
如果在實際的操作中,前面兩種情況交替出現(xiàn)呆躲,可以考慮使用List這樣的通用接口,而不用關心具體的實現(xiàn)捶索,再具體的情況下插掂,它的性能由具體的實現(xiàn)來保證。
HashMap腥例、HashTable辅甥、HashSet:
HashMap和HashTable采用的存儲機制是一樣的,不同的是:
1燎竖、HashMap:
a.? 采用數(shù)組方式存儲key-value構成的Entry對象璃弄,無容量限制;
b.? 基于key hash查找Entry對象存放到數(shù)組的位置构回,對于hash沖突采用鏈表的方式去解決夏块;
c.? 在插入元素時疏咐,可能會擴大數(shù)組的容量,在擴大容量時須要重新計算hash脐供,并復制對象到新的數(shù)組中浑塞;
d.? 是非線程安全的;
e.? 遍歷使用的是Iterator迭代器政己;
2酌壕、HashTable:
a. 是線程安全的;
b. 無論是key還是value都不允許有null值的存在歇由;在HashTable中調用Put方法時卵牍,如果key為null,直接拋出NullPointerException異常沦泌;
c. 遍歷使用的是Enumeration列舉糊昙;
3、HashSet:
a. 基于HashMap實現(xiàn)赦肃,無容量限制溅蛉;
b. 是非線程安全的;
c. 不保證數(shù)據(jù)的有序他宛;