HashMap、Hashtable、ConcurrentHashMap 核心对比

HashMap、Hashtable、ConcurrentHashMap 核心对比

一、整体概览

  • HashMap :单线程高性能,线程不安全
  • Hashtable :古老集合,全表 synchronized,线程安全但效率极低
  • ConcurrentHashMap :线程安全,分段锁 / CAS + synchronized,高并发首选

二、核心区别速查表

对比项 HashMap Hashtable ConcurrentHashMap
线程安全 ❌ 不安全 ✅ 安全 ✅ 安全
锁机制 无锁 方法全加 synchronized JDK7:分段锁 Segment JDK8:CAS + synchronized
效率 最高 最低 高(并发性能远胜 Hashtable)
key/value 是否允许 null key/value 都可 null key/value 都禁止 null key/value 都禁止 null
继承 继承 AbstractMap 继承 Dictionary 继承 AbstractMap
默认容量 16 11 16
扩容 容量 ×2 容量 ×2+1 同 HashMap
哈希冲突 JDK7:数组+链表 JDK8:数组+链表+红黑树 数组+链表 JDK8:数组+链表+红黑树
迭代器 快速失败 fail-fast 快速失败 fail-fast 安全失败 fail-safe

三、详细说明

1. HashMap(最常用)

  • 单线程环境下性能最好
  • 线程不安全,高并发会出现数据丢失、死循环
  • key 和 value 都可以为 null(只能有一个 key 为 null)
  • JDK8 优化:链表长度 ≥8 转为红黑树,≤6 退化为链表
  • 扩容机制:达到负载因子 0.75 时扩容为原来 2 倍

2. Hashtable(基本废弃)

  • 线程安全靠 方法级别 synchronized
  • 锁整个哈希表,并发能力极差
  • 不允许 null key / null value
  • 历史遗留类,不推荐使用

3. ConcurrentHashMap(高并发标准方案)

JDK 1.7
  • 采用 Segment 分段锁
  • 默认 16 个 Segment,每段一把锁
  • 支持 16 个线程并发
JDK 1.8(重大优化)
  • 取消 Segment,直接用 数组 + 链表 + 红黑树
  • 锁粒度降低:只锁链表/红黑树的头节点
  • 读操作无锁,使用 CAS + volatile
  • 写操作使用 synchronized + CAS
  • 并发性能大幅提升

四、底层扩容机制(通用)

  1. 初始容量默认 16
  2. 负载因子默认 0.75
  3. 元素数量 > 容量 × 0.75 时触发扩容
  4. 扩容为 原容量 × 2
  5. 重新计算所有元素哈希位置

五、为什么 ConcurrentHashMap 不允许 null?

  • 多线程场景下,get(key) == null 无法区分是 key 不存在 还是 value 为 null
  • 为避免歧义,严格禁止 null

HashMap 单线程无歧义,所以允许 null。


六、使用场景总结

  1. 单线程 → 用 HashMap
  2. 高并发 → 用 ConcurrentHashMap
  3. Hashtable → 基本废弃,不要用

七、高频面试题

  1. HashMap 为什么线程不安全?

    多线程同时扩容可能形成环形链表,导致死循环;同时 put 可能覆盖值。

  2. ConcurrentHashMap 在 JDK7 和 JDK8 的区别?

    JDK7:Segment 分段锁

    JDK8:CAS + synchronized + 红黑树,锁粒度更小,性能更高。

  3. 为什么 HashMap 允许 null,ConcurrentHashMap 不允许?

    多线程无法区分 null 是没找到还是值本身为 null。

  4. HashMap 哈希冲突怎么解决?

    链地址法,JDK8 加入红黑树优化。

相关推荐
南归北隐3 分钟前
Spring AI Alibaba Graph框架实现RAG私有知识库问答
java·后端·spring·spring ai·java rag实现
从琳开始98916 分钟前
[JavaEE]多线程初阶(下篇)------多线程案例(单例模式,阻塞队列,线程池,定时器)
java·单例模式·java-ee
乌暮20 分钟前
# Spring 入门与 Spring MVC 实战指南:从零理解 IoC 到 RESTful 图书管理
java·开发语言·后端·学习·spring·mvc·restful
java1234_小锋22 分钟前
Spring Boot 4.0 官宣:弃用 Undertow
java·spring boot·后端
jyOverQ25 分钟前
Redis 主从复制、Sentinel 和 Cluster 到底有什么区别?
java·redis·sentinel
青春逝如流水37 分钟前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
wangbing11252 小时前
springboot应用关闭时触发动作
java·spring boot·后端
weixin_460443565 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
海鸥-w8 小时前
什么是AOP
java
Cc.Y9 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python