news 2026/8/6 17:47:03

HashMap、HashTable、ConcurrentHashMap 详细区别与深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HashMap、HashTable、ConcurrentHashMap 详细区别与深度解析

一、引言

在 Java 集合框架中,HashMapHashTableConcurrentHashMap是三个核心的哈希表实现,它们在并发性、线程安全性、性能和使用场景上有着显著差异。理解这些区别对于编写高效、健壮的 Java 程序至关重要。本文将深入剖析这三者的底层原理、特性对比以及适用场景。

二、核心特性概览

特性HashMapHashTableConcurrentHashMap
线程安全是(方法级 synchronized)是(分段锁/CAS)
允许 null 键/值否(键值均不允许)
继承体系继承 AbstractMap继承 Dictionary继承 AbstractMap
默认初始容量161116
扩容机制2 的幂次方2n+12 的幂次方
迭代器快速失败(Fail-Fast)快速失败(Fail-Fast)弱一致性(Weakly Consistent)
性能(单线程)较低较高
性能(高并发)不安全,需外部同步低(锁竞争严重)高(锁粒度细)
Java 版本1.2+1.0+1.5+

三、HashMap 深度解析

3.1 基本特性

HashMap是 Java 集合框架中最常用的哈希表实现,基于数组+链表/红黑树(JDK 8+)的结构。它不保证元素的顺序,且允许一个null键和多个null值。

3.2 线程安全性

HashMap是非线程安全的。在多线程环境下,如果多个线程同时修改HashMap(如 put、remove),可能会导致数据不一致、死循环(JDK 7 及之前)或元素丢失等问题。

3.3 扩容机制

当元素数量超过容量与负载因子(默认 0.75)的乘积时,HashMap会进行扩容,容量变为原来的 2 倍。扩容时,会重新计算所有元素的位置(rehash)。

3.4 代码示例

import java.util.HashMap; public class HashMapDemo { public static void main(String[] args) { HashMap<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("banana", 2); map.put(null, 3); // 允许 null 键 map.put("orange", null); // 允许 null 值 System.out.println(map.get("apple")); // 输出: 1 System.out.println(map.containsKey(null)); // 输出: true } }

四、HashTable 深度解析

4.1 基本特性

HashTable是 Java 早期的哈希表实现,属于遗留类(Legacy Class)。它是线程安全的,通过在方法上添加synchronized关键字实现。不允许null键和null值。

4.2 线程安全性实现

HashTable使用对象级别的锁(synchronized 方法),即对整个哈希表加锁。这保证了线程安全,但在高并发场景下会导致严重的锁竞争,性能低下。

4.3 与 HashMap 的主要区别

  • 线程安全HashTable线程安全,HashMap非线程安全。
  • Null 值HashTable不允许 null 键/值,HashMap允许。
  • 继承父类HashTable继承DictionaryHashMap继承AbstractMap
  • 迭代器HashTable使用EnumerationHashMap使用Iterator

4.4 代码示例

import java.util.Hashtable; public class HashTableDemo { public static void main(String[] args) { Hashtable<String, Integer> table = new Hashtable<>(); table.put("apple", 1); table.put("banana", 2); // table.put(null, 3); // 抛出 NullPointerException // table.put("orange", null); // 抛出 NullPointerException System.out.println(table.get("apple")); // 输出: 1 } }

五、ConcurrentHashMap 深度解析

5.1 基本特性

ConcurrentHashMap是 Java 5 引入的并发哈希表,专为高并发场景设计。它提供了比HashTable更好的并发性能,同时保证了线程安全。

5.2 线程安全性实现(演进)

  • JDK 7:采用分段锁(Segment)机制,将整个哈希表分成多个段(Segment),每个段独立加锁,提高了并发度。
  • JDK 8 及以后:摒弃分段锁,采用synchronized+CAS(Compare-And-Swap)实现。锁的粒度更细(锁住单个链表头节点或红黑树根节点),并发性能进一步提升。

5.3 关键特性

  • 不允许 null 键/值:设计上避免二义性(无法区分 key 不存在还是值为 null)。
  • 弱一致性迭代器:迭代器创建后,可能反映或可能不反映更新操作,但不会抛出ConcurrentModificationException
  • 高并发读:读操作通常不需要加锁,性能接近HashMap

5.4 代码示例

import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapDemo { public static void main(String[] args) { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("apple", 1); map.put("banana", 2); // map.put(null, 3); // 抛出 NullPointerException // map.put("orange", null); // 抛出 NullPointerException // 线程安全的复合操作 map.computeIfAbsent("pear", k -> 4); System.out.println(map.get("pear")); // 输出: 4 } }

六、三者对比与选型建议

6.1 性能对比

  • 单线程环境HashMap>ConcurrentHashMap>HashTable
  • 低并发读写ConcurrentHashMap>HashMap(需外部同步)>HashTable
  • 高并发读写ConcurrentHashMap显著优于HashTable

6.2 选型指南

  1. 单线程应用:优先使用HashMap,性能最佳。
  2. 低并发,需要线程安全:可使用Collections.synchronizedMap(new HashMap<>())ConcurrentHashMap
  3. 高并发场景:必须使用ConcurrentHashMap
  4. 遗留系统或特定 API 要求:才考虑使用HashTable
  5. 需要 null 键/值:只能选择HashMap

6.3 常见面试题要点

  • HashMap 线程不安全的表现:扩容时可能形成环形链表(JDK 7)、数据覆盖、size 不准确。
  • ConcurrentHashMap 如何保证线程安全:JDK 7 分段锁,JDK 8+ synchronized + CAS + volatile。
  • 为什么 ConcurrentHashMap 不允许 null:避免二义性,简化并发逻辑。
  • 快速失败 vs 弱一致性迭代器:前者在检测到并发修改时立即抛出异常,后者容忍并发修改,但不保证实时性。

七、总结

HashMapHashTableConcurrentHashMap分别代表了非线程安全、粗粒度线程安全和细粒度高性能线程安全三种设计哲学。在现代 Java 开发中,HashMap是单线程首选,ConcurrentHashMap是多线程标配,而HashTable已基本被淘汰。理解其底层实现和适用场景,有助于我们根据实际需求做出最合适的技术选型。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/6 17:37:01

小说写文发布一体工具,结合创作流程的选型参考

很多网文创作者都会面临同一个困扰。从构思灵感、搭建大纲、撰写章节&#xff0c;直到最终上传平台发布&#xff0c;常常需要来回切换多款软件。人设档案存放在笔记软件&#xff0c;正文在AI工具生成&#xff0c;定稿章节还要复制粘贴到作家后台&#xff0c;多本小说同时更新时…

作者头像 李华
网站建设 2026/8/6 17:35:30

STM32蜂鸣器播放音乐:PWM原理与《菊次郎的夏天》实现

1. 项目概述&#xff1a;当单片机遇上经典旋律最近在捣鼓一个基于STM32的小玩意儿&#xff0c;想让它用最普通的蜂鸣器或者小喇叭&#xff0c;把《菊次郎的夏天》那首经典的“Summer”给演奏出来。这听起来像是个简单的电子DIY&#xff0c;但真做起来&#xff0c;你会发现里面融…

作者头像 李华
网站建设 2026/8/6 17:34:07

不用挖开整片场地,G-6000 助力定位风光电站地下故障光缆

风光、储能基地通信光缆大多采用埋地铺设方式&#xff0c;施工剐蹭、土层挤压等情况&#xff0c;容易造成光纤断裂。过去抢修作业常常依靠残缺的管线图纸开展大面积开挖&#xff0c;容易误伤完好管线&#xff0c;进一步延长发电停机时长。G-6000 光缆路由智能定位仪借助振动传感…

作者头像 李华
网站建设 2026/8/6 17:32:28

KubeSphere学习笔记:部署nginx

&#x1f4dd; 本文首发于 栏轩阁 欢迎访问阅读原文&#xff0c;获取更好的阅读体验。 一、前言 本文在已有 KubeSphere 环境和 K8s 集群的基础上&#xff0c;记录如何通过 KubeSphere 部署一个完整的 Nginx 网站。 适用场景 已在本地通过 Docker Desktop 启用 K8s 集群已安…

作者头像 李华
网站建设 2026/8/6 17:27:26

5步轻松修复损坏二维码:QRazyBox终极指南拯救重要信息

5步轻松修复损坏二维码&#xff1a;QRazyBox终极指南拯救重要信息 【免费下载链接】qrazybox QR Code Analysis and Recovery Toolkit 项目地址: https://gitcode.com/gh_mirrors/qr/qrazybox 你是否遇到过模糊不清的二维码无法扫描&#xff1f;或者精心设计的二维码因部…

作者头像 李华