HashMap、HashTable和ConcurrentHashMap底层实现有什么区别?
在面试过程中面试官会经常问到HashMap
和HashTable
的底层实现和区别,以下是对其做了简单的总结。
HashMap
的实现原理:
HashMap
是基于hash
,底层是由数组加上链表的数据结构。
我们通过put()
和get()
方法来存储和获取对象,当将键值传入put()
方法时,它调用键值对应的hashCode()
方法来计算hashCode
,通过hashCode
找到数组的存储位置来存储值对象,HashMap
使用链表来解决碰撞问题,当发生冲突时就在数组元素所在链表的表头插入该值;当获取对象时,先通过key
的hashCode
值定位到数组的位置,遍历该位置的链表,再由equals
找到正确的键值,找到满足要求的节点返回。
HashTable
的实现原理
HashTable
的底层也是由数组加上链表的数据结构。HashTable
类继承自Dictionary
类,实现了Map
、Cloneable
和java.io.Serializable
HashTable
与HashMap
中的功能相同。而HashTable
所有的操作都是通过synchronized
锁保护的。再存储数据时,先获取synchronized
锁,通过key
的哈希值计算出数组位置来存储值对象。获取对象时,首先也是先获得synchronized
锁,通过key
的hashCode
值定位到数组的位置,遍历该位置的链表,再由equals
找到正确的键值,找到满足要求的节点返回。
ConcurrentHashMap
的实现原理
相比HashMap
在多线程环境下不安全和HashTable
的效率低下,ConcurrentHashMap
则采用了一种分段锁的技术,ConcurrentHashMap
是由Segment
数组结构和HashEntry
数组结构组成;将存储的数据分成多个Segment
,在每一个Segment
上有一把锁,当多线程访问容器里不同数据段的数据时,线程间就不会存在锁的竞争,从而提高并发访问的效率。
Segment
是一种可重入锁ReentrantLock
,在ConcurrentHashMap
中扮演锁的角色,HashEntry
则用于存储键值对数据。一个ConcurrentHashMap
里包含一个Segment
数组,Segment
的结构和HashMap
类似,是一种数组和链表结构,一个Segment
里包含一个HashEntry
数组,每个HashEntry
是一个链表结构的元素,每个Segment
守护着一个HashEntry
数组里的元素,当对HashEntry
数组的数据进行修改时,必须首先获得它对应的Segment
锁。
- 关于
HashMap
和HashTable
的区别
HashTable
是基于Dictionary
类,HashMap
是实现了Map
接口。HashTable
是同步的线程安全的,每个方法上都加了synchronized
关键字。HashMap
则不是线程安全的。也可以用collections
类的synchronizedMap()
方法创建一个线程安全的Map
对象。HashMap
中的key
和value
是允许为空的,即HashMap
中只有一条可以是空的key
,但可以有任意条空的value
。而HashTable
的key
和value
不允许为空。
原文作者: dgb8901,yinxing
原文链接: https://www.itwork.club/2018/07/13/hashMap-hashTable/
版权声明: 转载请注明出处
为您推荐
体验小程序「简易记账」
关注公众号「特想学英语」