当前位置: 首页 > news >正文

HashMap、HashTable 与 ConcurrentHashMap 的区别

HashMap、HashTable 与 ConcurrentHashMap 深度解析


1. 核心设计差异与演进背景
  1. 线程安全机制

  2. Null 支持

    • HashMap:允许一个 null 键和多个 null 值(null 键默认存储在数组首位置)。
    • HashTable 与 ConcurrentHashMap:均不允许 null 键或值,插入 null 会抛出 NullPointerException

2. 数据结构与扩容机制
  1. HashMap

    • 底层结构:数组 + 链表 + 红黑树(Java 8+)。链表长度 ≥8 且数组长度 ≥64 时,链表转为红黑树(查找复杂度从 O(n) 降至 O(log n))1。
    • 扩容规则:默认初始容量 16,负载因子 0.75。扩容时容量翻倍(newSize = oldSize * 2),所有元素重新计算哈希并迁移1。
    • 哈希优化:使用扰动函数 hash = key.hashCode() ^ (h >>> 16) 减少哈希冲突
  2. HashTable

  3. ConcurrentHashMap

    • 底层结构:与 HashMap 类似(Java 8+ 后均为数组+链表+红黑树),但扩容更智能:
      • 分阶段扩容:多线程协作迁移数据,避免长时间阻塞。
      • 扩容期间允许读写:新旧表共存,读操作访问旧表,写操作插入新表。
    • 扩容触发:单个链表/红黑树长度超过阈值时触发段内扩容,而非全局扩容

3. 性能对比与适用场景
指标HashMapHashTableConcurrentHashMap
线程安全是(全局锁)是(分段锁/CAS)
并发性能高(单线程)极低接近 HashMap(高并发场景)
Null 支持
推荐场景单线程、快速查询已淘汰(遗留系统)高并发读写(缓存、计数器)

4. 关键源码与设计思想
  1. HashMap 的哈希冲突处理

    • 链表转红黑树:解决长链表查询效率问题,但转换成本较高(需遍历链表生成树节点)。
    • 负载因子调优:默认 0.75 是空间与时间的平衡,可通过调整初始容量减少扩容频率
  2. ConcurrentHashMap 的无锁优化

    • CAS 操作:用于插入、替换等轻量级操作,避免锁竞争。
    • Node 锁:仅对当前操作的链表头节点或红黑树根节点加锁,其他节点可并发访问。

5. 实战建议与避坑指南
  1. 避免 HashTable:其全局锁设计已过时,推荐使用 ConcurrentHashMapCollections.synchronizedMap()(需手动同步迭代器)。
  2. HashMap 的线程安全替代方案
    • 单线程场景:优先使用 HashMap
    • 多线程读多写少:使用 ConcurrentHashMap
    • 高并发写场景:结合 ConcurrentHashMap 和原子类(如 AtomicInteger)实现计数器。
  3. 扩容预判:初始化时预估容量(如 new HashMap<>(expectedSize / 0.75 + 1))以减少扩容次数

6. 总结
  • HashMap:单线程之王,非线程安全但效率最高。
  • HashTable:历史遗留产物,性能低下,不推荐使用。
  • ConcurrentHashMap:高并发场景的首选,兼顾线程安全与性能,设计上采用分段锁和 CAS 实现高效并发

选择原则

  • 若无需线程安全,首选 HashMap
  • 若需线程安全且高并发,必选 ConcurrentHashMap
  • 避免使用 HashTable,除非维护遗留代码。

相关文章:

  • 从入门到精通【 MySQL】 数据库约束与设计
  • 小学数学解题方法专题3-列表法-提升2
  • MySQL 8.X 仅迁移非系统数据库账号和权限信息
  • 工地扬尘监测仪:守护蓝天白云的重要工具
  • golang的database.sql包和事务处理
  • JAVA实战开源项目:体育馆使用预约平台(Vue+SpringBoot) 附源码
  • 音视频学习(三十一):DASH协议
  • 测试用例管理工具
  • Opencv计算机视觉编程攻略-第四节 图直方图统计像素
  • tsconfig.json:error TS6306: Referenced project ‘/tsconfig.node.json‘
  • (二)GEE基础学习初探及案例详解【20250330】
  • .global
  • Nginx — Nginx处理Web请求机制解析
  • 华为数字化转型-方法篇
  • 记一个很简单的错误
  • 蓝桥杯备赛:力扣刷题——寻找两个正序数组中的中位数
  • 最长子序列
  • HTML中的<form>表单及其元素
  • 17.C语言数组
  • 常见的响应头信息
  • 怎么做电影网站不违法/南京seo外包
  • 黑龙江外贸网站制作/企业网络营销策划案例
  • 学做网站论坛vip账户/seo技术是干什么的
  • 内蒙古做网站的公司/带佣金的旅游推广平台有哪些
  • 备案域名做的网站别人用来诈骗/东莞网站制作十年乐云seo
  • qq刷赞网站怎么做的/宁波网站优化公司电话