线程进阶 --- HashMap、HashTable和ConcurrentHashMap

简介: 线程进阶 --- HashMap、HashTable和ConcurrentHashMap

一、什么是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 如何进行锁策略优化的?


5edcd8accbf940b2a3de2fa9b76fe663.png


158d4f81748c48b5ad79da54e1766245.png


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机制,优化了扩容方式 不允许


相关文章
|
9月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
141 3
|
10月前
|
安全
HashTable与HashMap的区别
(1)HashTable的每个方法都用synchronized修饰,因此是线程安全的,但同时读写效率很低 (2)HashTable的Key不允许为null (3)HashTable只对key进行一次hash,HashMap进行了两次Hash (4)HashTable底层使用的数组加链表HashTable与HashMap的区别
148 2
|
10月前
|
安全
ConcurrentHashMap原如何保证的线程安全?
JDK1.7:使用分段锁,将一个Map分为了16个段,每个段都是一个小的hashmap,每次操作只对其中一个段加锁 JDK1.8:采用CAS+Synchronized保证线程安全,每次插入数据时判断在当前数组下标是否是第一次插入,是就通过CAS方式插入,然后判断f.hash是否=-1,是的话就说明其他线程正在进行扩容,当前线程也会参与扩容;删除方法用了synchronized修饰,保证并发下移除元素安全
244 2
|
11月前
|
存储 开发者
HashMap和Hashtable的key和value可以为null吗,ConcurrentHashMap呢
HashMap的key可以为null,value也可以为null;Hashtable的key不允许为null,value也不能为null;ConcurrentHashMap的key不允许为null
|
存储 Java 开发者
HashMap线程安全问题大揭秘:ConcurrentHashMap、自定义同步,一文让你彻底解锁!
【8月更文挑战第24天】HashMap是Java集合框架中不可或缺的一部分,以其高效的键值对存储和快速访问能力广受开发者欢迎。本文深入探讨了HashMap在JDK 1.8后的底层结构——数组+链表+红黑树混合模式,这种设计既利用了数组的快速定位优势,又通过链表和红黑树有效解决了哈希冲突问题。数组作为基石,每个元素包含一个Node节点,通过next指针形成链表;当链表长度过长时,采用红黑树进行优化,显著提升性能。此外,还介绍了HashMap的扩容机制,确保即使在数据量增大时也能保持高效运作。通过示例代码展示如何使用HashMap进行基本操作,帮助理解其实现原理及应用场景。
202 1
|
安全 Java
【Java集合类面试十五】、说一说HashMap和HashTable的区别
HashMap和Hashtable的主要区别在于Hashtable是线程安全的,不允许null键和值,而HashMap是非线程安全的,允许null键和值。
|
安全 Java
【Java集合类面试十六】、HashMap与ConcurrentHashMap有什么区别?
HashMap是非线程安全的,而ConcurrentHashMap通过减少锁粒度来提高并发性能,检索操作无需锁,从而提供更好的线程安全性和性能。
|
开发者 C# UED
WPF与多媒体:解锁音频视频播放新姿势——从界面设计到代码实践,全方位教你如何在WPF应用中集成流畅的多媒体功能
【8月更文挑战第31天】本文以随笔形式介绍了如何在WPF应用中集成音频和视频播放功能。通过使用MediaElement控件,开发者能轻松创建多媒体应用程序。文章详细展示了从创建WPF项目到设计UI及实现媒体控制逻辑的过程,并提供了完整的示例代码。此外,还介绍了如何添加进度条等额外功能以增强用户体验。希望本文能为WPF开发者提供实用的技术指导与灵感。
478 0
|
存储 安全 Java
Hashtable 和 HashMap 的区别
【8月更文挑战第22天】
611 0
|
2月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
117 0