1.关于HashMap的底层实现
HashMap的存储逻辑
HashMap的数据结构构成:数组+链表+红黑树(红黑树是jdk1.8才引入的)
JDK1.7 使用了数组+链表的方式
JDK1.8 使用了数组+链表+红黑树的方式
JDK8中HashMap引入了红黑树,同时在ConcurrentHashMap中做了相应优化。
ConcurrentHashMap是jdk1.5引入的
图摘自《HashMap的实现原理,源码深度剖析! – mikechen》
数组:transient Node<K,V>[] table 哈希桶数组
其元素类型是Node,Node是HashMap的内部类,实现了Map.Entry接口(本质是键值映射)
数组结构是Hash Table哈希表|散列表,根据key查找value : value=table[hash(key)]
数组长度总是2的n次方
核心问题:Hash冲突,Key不相同,但hash(Key)的值相同
Hash冲突的解决方法有: 地址法、链地址法,此处采用链地址法
就是在table数组本该放置元素的位置放置一个链表,把冲突的值链接在链表上,当链表过长时,将其转换为红黑树
图摘自《HashMap和ConcurrentHashMap的区别,详解HashMap和ConcurrentHashMap数据结构-CSDN博客》
2.HashMap实现逻辑
(1).Hash函数的使用:
(2).数组槽位运算
(3).put方法的操作流程
参考《【hashmap】HashMap原理及线程不安全详解|哈希表原理-CSDN博客》
参考《HashMap的实现原理,源码深度剖析! – mikechen》
(4).get方法的操作流程
(5).HashMap扩容
3.HashMap的锁与安全机制
(1).HashMap线程不安全-扩容死链
(2)ConcurrentHashMap如何保证线程安全
(a).JDK1.7 ConcurrentHashMap锁分离的线程安全机制
(b).JDK1.8 Synchronized和CAS来操作的线程安全机制
4.知识点补充
CAS:
自旋锁:
ReentrantLock: