谈谈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,其他两个不允许


相关文章
|
11天前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
11天前
|
并行计算 数据挖掘 大数据
[go 面试] 并行与并发的区别及应用场景解析
[go 面试] 并行与并发的区别及应用场景解析
|
5天前
|
存储 安全 Java
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)
这篇文章是关于Java面试的第二天笔记,涵盖了HashMap与HashTable的区别、ConcurrentHashMap的实现原理、IOC容器的实现方法、字节码的概念和作用、Java类加载器的类型、双亲委派模型、Java异常体系、GC如何判断对象可回收、线程的生命周期及状态,以及sleep、wait、join、yield的区别等十道面试题。
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)
|
5天前
|
存储 关系型数据库 MySQL
一天五道Java面试题----第八天(怎么处理慢查询--------->简述Myisam和innodb的区别)
这篇文章是关于Java面试中关于数据库性能优化和MySQL特性的五个问题,包括处理慢查询、ACID特性保证、MVCC概念、MySQL主从同步原理以及MyISAM和InnoDB存储引擎的区别。
|
10天前
|
Java 调度
搞清楚wait、sleep、join、yield四者区别,面试官直接被征服!
掌握上述多线程控制方法的运用,可以在Java多线程程序编写中进行更加深入的线程管理,确保程序运行更加高效、稳定。在面试中准确并熟练地讲解这些概念,确实有可能让面试官对你的专业能力留下深刻印象。
17 0
|
3天前
|
存储 缓存 网络协议
复盘女朋友面试4个月的Java基础题
这篇文章是关于Java基础面试题的复盘,涵盖了HashMap原理、对象序列化作用等高频面试问题,并强调了Java基础知识的重要性。
复盘女朋友面试4个月的Java基础题
|
5天前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
28天前
|
SQL Java Unix
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
31 3
|
1月前
|
存储 算法 Java
Java面试之SpringCloud篇
Java面试之SpringCloud篇
67 1
|
1月前
|
SQL 关系型数据库 MySQL
java面试之MySQL数据库篇
java面试之MySQL数据库篇
35 0
java面试之MySQL数据库篇