谈谈HashTable, HashMap, ConcurrentHashMap 之间的区别(一道经典的面试题)

简介: 谈谈HashTable, HashMap, ConcurrentHashMap 之间的区别(一道经典的面试题)

一、HashMap

HashMap没有对线程安全做任何有效的措施,是线程不安全的

04f3a86186e94e688e2d3e95fbd9f0da.png

二、HashTable

我们可以看到在HashTable的源码当中,只是简单的把关键方法加上了 synchronized 关键字,这样就相当于是直接针对HashTable对象本身进行了加锁

66593e13294a4c46a3e9bed8fc09fbee.png

268acdd19305458aa0d4bc3bbff70421.png

但这样做虽然保证了线程安全,但也存在着一些问题:


很多时候不同的线程所操作的是不同的哈希桶(链表),并不会产生线程安全问题,但HashTable仍然一棒子打死——对整体加了锁

size 属性也是通过 synchronized 来控制同步, 也是比较慢的.

一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低.

三、ConcurrentHashMap

于是ConcurrentHashMap相比于 Hashtable 做出了一系列的改进和优化. 以 Java1.8 为例

1、ConcurrentHashMap把锁的粒度细化了,对每一个哈希桶都加了锁(lock锁)————这样只有当不同线程对同一个哈希桶中的元素进行操作时才会产生冲突,因为一个哈希表有很多哈希桶,这就大大降低了冲突的概率

3f29bf0de67243fd8c049e751dd96094.png


2、充分利用 CAS 特性. 比如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况


3、优化了扩容方式: 化整为零


发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.

扩容期间, 新老数组同时存在.

后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.

搬完最后一个元素再把老数组删掉.

这个期间, 插入只往新数组加.

这个期间, 查找需要同时查新数组和老数组

四、总结

1.HashMap线程不安全、HashTable、ConcurrentHashMap线程安全

2.HashTable是整体加了一把大锁,发生锁竞争的概率较大。ConcurrentHashMap是给数组的每个下标所对应的哈希桶都加了一把锁,把锁细分了,大大降低了发生锁竞争的概率。

3.ConcurrentHashMap充分利用了CAS机制,优化了扩容方式

4.HashMap的key允许为null,其他两个不允许


相关文章
|
20天前
|
安全
HashTable与HashMap的区别
(1)HashTable的每个方法都用synchronized修饰,因此是线程安全的,但同时读写效率很低 (2)HashTable的Key不允许为null (3)HashTable只对key进行一次hash,HashMap进行了两次Hash (4)HashTable底层使用的数组加链表HashTable与HashMap的区别
23 2
|
2月前
|
存储 开发者
HashMap和Hashtable的key和value可以为null吗,ConcurrentHashMap呢
HashMap的key可以为null,value也可以为null;Hashtable的key不允许为null,value也不能为null;ConcurrentHashMap的key不允许为null
|
27天前
|
存储 缓存 安全
大厂面试高频:ConcurrentHashMap 的实现原理( 超详细 )
本文详细解析ConcurrentHashMap的实现原理,大厂高频面试,必知必备。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:ConcurrentHashMap 的实现原理( 超详细 )
|
1月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
32 1
|
2月前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
41 1
|
2月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
161 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
前端开发 小程序 JavaScript
面试官:px、em、rem、vw、rpx 之间有什么区别?
面试官:px、em、rem、vw、rpx 之间有什么区别?
52 0
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
28天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?