HashMap 1.7 底層使用的數據結構是數組+鏈表,鏈表是爲了解決hash碰撞的,相同的值插入,鏈表的插入採用的是頭插法。多線程插入會出現循環鏈表問題。
HashMap 1.8 底層使用的數據結構是數組+鏈表+紅黑樹,鏈表是爲了解決hash碰撞的,紅黑樹是解決鏈表長度過長的查詢問題。
此處鏈表的插入採用的是尾插法。
HashTable ConcurrentHashMap 是解決HashMap 線程不安全的問題,HashTable 是加方法級別的鎖,方法上加Synchronized
HashTable 鎖的力度較大,解決HashTable力度較大的問題出現ConcurentHashMap,ConcurrentHashMap 添加Segment的分段鎖,力度較小。java 1.8 使用CAS+Synchronized 代碼段的鎖,力度更小。性能更好。
使用源碼證明:
java1.7
HashMap 常量
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; --------------初始數組容量 16
static final float DEFAULT_LOAD_FACTOR = 0.75f;------------------動態擴容因子
1.HashMap的put操作:
2.數組庫容的條件
3.擴容的函數
4.在鏈表中插入節點
5.鏈表中的每一個節點
ConcurrentHashMap:
concurrentHashmap在1.7和1.8 的區別
currentHashMap 在1.7 採用鎖保證線程安全,分段鎖 segment
currentHashMap 在1.8 採用cas+sycchronized 實現細粒度的鎖
1.7
ConcurrentHashMap 下面是一個Segment[] 數組,每個Segment 下面是一個 HashEntry[] 數組
segment 繼承ReentrantLock
Segment 的put進行加鎖
釋放鎖
1.8 的CurrentHashMap
HashTable 方法級別的鎖:
參考:
1.https://www.jianshu.com/p/5dbaa6707017----java ConcurrentHashMap
2.https://www.jianshu.com/p/cda24891f9e4--- unsafe類 cas樂觀鎖