目录
1. ConcurrentHashMap 的读操作是否加锁?
2. 介绍下ConcurrentHashMap 的锁分段技术?
3. ConcurrentHashMap 为什么在jdk1.8就没了?又做了怎样的优化?
4. Hashtable 和 hashMap 、ConcurrentHashMap之间的区别:
🐖🐖🐖🐖如果喜欢!!🐂🐂🐂🐂
🐖🐖🐖🐖欢迎关注!!🐂🐂🐂🐂
🐖🐖🐖🐖持续回访! !🐂🐂🐂🐂
CSDN主页:所有博客内容,Java大树逐渐成长
Gitee地址:想看博客代码??点击这里
一、什么是HashMap?
单线程中使用。
- HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
- HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
- HashMap 是无序的,即不会记录插入的顺序。
- HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。
二、什么是Hashtable?
无脑加锁版本的HashMap。不建议使用。
- 和HashMap的基本功能一样,但是在多线程操作中,HashMap是线程不安全的,但是Hashtable是线程安全的。
- 如果多线程访问同一个Hashtable就会直接造成锁冲突。
- size属性也是通过synchronized来控制同步,也是比较慢的。
- 一旦触发扩容,就又该线程完成整个扩容过程,会涉及到大量元素拷贝,效率很低
三、什么是ConcurrentHashMap?
超级优化的Hashtable。适合多线程。
相对于 Hashtable 如何进行锁策略优化的?
ConcurrentHashMap大大降低了锁的粒度。
这样每个哈希桶都有自己的一把锁就大大降低了锁竞争的概率,使代码效率大大提高。因此在多线程案例使用过程中,我们一般直接就会选择 ConcurrentHashMap。
三、相关面试题
1. ConcurrentHashMap 的读操作是否加锁?
不加锁!一般只是读操作而没有修改数据的,都不需要加锁。而是需要搭配volatile关键字,保证每次读取到的数据都是新数据。
2. 介绍下ConcurrentHashMap 的锁分段技术?
jdk1.7中使用了锁分段技术,而jdk1.8就没有再使用了,简单地说就是:
把每一个哈希桶都分成一个“段” , 而每一个段又都有一个锁,针对每个段进行加锁,就降低了锁竞争的概率,只有当两个线程访问的数据恰好在同一个 段 上的时候才会发生锁竞争。
3. ConcurrentHashMap 为什么在jdk1.8就没了?又做了怎样的优化?
jdk1.8把HashMap、ConcurrentHashMap等一些库的实现改变了:将原来的 数组+链表 的实现方式改成了 数组+链表/红黑树。当链表较长的时候(>=8个元素)就转化为了红黑树。
而在ConcurrentHashMap中 取消了分段锁,直接给每个哈希桶(即每个链表) 分配了一个锁,就是直接以每个链表的头结点作为锁对象。
4. Hashtable 和 hashMap 、ConcurrentHashMap之间的区别:
类 名称 | 加锁方式 | key是否允许为null |
---|---|---|
HashMap | 无加锁,线程不安全 | 允许 |
Hashtable | 一把大锁:使用synchronized锁hashtable对象,效率较低 | 不允许 |
ConcurrentHashMap | 很多小锁:使用synchronized锁每个链表的头结点,锁冲突概况低,充分利用了CAS机制,优化了扩容方式 | 不允许 |