實現(xiàn)原理
- 底層實現(xiàn)是數(shù)組,數(shù)組項為鏈表,Entry<K,V>。
- 存值時,若有2個key的hash值相同,則會比較key是否相同,相同則覆蓋,不同則用鏈表串起來。
- 取值時,通過key對應(yīng)的hash值找到在table數(shù)組中的索引處的Entry,然后返回該key對應(yīng)的value即可。
- 線程不安全的點:存值和擴容時。尤其在擴容時還可能導(dǎo)致死循環(huán),直接把應(yīng)用搞掛。
可選擇的線程安全的Map
Hashtable , synchronizedMap , ConcurrentHashMap
HashTable和synchronizedMap鎖住了整個Map,CHM只鎖住部分Map。所以CHM效率最高。
ConcurrentHashMap的實現(xiàn)
在 ConcurrentHashMap內(nèi)部有一個Segment段,它將大的HashMap切分成若干個段(小的HashMap),然后讓數(shù)據(jù)在每一段上Hash,這樣多個線程在不同段上的Hash操作一定是線程安全的,所以只需要同步同一個段上的線程就可以了,這樣實現(xiàn)了鎖的分離,大大增加了并發(fā)量。
- CHM默認的并發(fā)級別是16,但可以在創(chuàng)建CHM時通過構(gòu)造函數(shù)改變。毫無疑問,并發(fā)級別代表著并發(fā)執(zhí)行更新操作的數(shù)目,所以如果只有很少的線程會更新Map,那么建議設(shè)置一個低的并發(fā)級別。另外,CHM還使用了ReentrantLock來對segments加鎖。
- putIfAbsent
- CHM允許并發(fā)的讀和線程安全的更新操作
在執(zhí)行寫操作時,CHM只鎖住部分的Map
并發(fā)的更新是通過內(nèi)部根據(jù)并發(fā)級別將Map分割成小部分實現(xiàn)的
高的并發(fā)級別會造成時間和空間的浪費,低的并發(fā)級別在寫線程多時會引起線程間的競爭
CHM的所有操作都是線程安全
CHM返回的迭代器是弱一致性,fail-safe并且不會拋出ConcurrentModificationException異常
CHM不允許null的鍵值
可以使用CHM代替HashTable,但要記住CHM不會鎖住整個Map