Hashtable未被@Deprecated标记但已被官方明确不推荐使用,因其全表同步锁导致性能差、不支持null、API陈旧且迭代器非fail-fast,现代开发应优先选用HashMap(单线程)或ConcurrentHashMap(多线程)。

Hashtable 被现代 Java 开发彻底淘汰,不是因为“不能用”,而是因为它在设计、性能和维护性上全面落后于更优的替代方案。它属于 JDK 1.0 时代的遗留类,早已被明确标记为 @Deprecated(虽未正式加注 @Deprecated 注解,但官方文档和最佳实践中已强烈不推荐)。
同步机制太粗暴,性能严重拖后腿
Hashtable 所有 public 方法(put、get、size、containsKey 等)都用 synchronized 修饰,意味着每次操作都要获取整个 Map 的独占锁。这种“全表锁”在高并发下会造成严重线程争抢:
- 哪怕两个线程操作完全不相关的键(比如 key="user1" 和 key="order99"),也必须排队等待同一把锁
- 读操作也被阻塞——而读操作本可并发执行
- 吞吐量随线程数增加不升反降,远不如 ConcurrentHashMap
功能受限,null 处理不友好
它强制禁止键和值为 null,一插入就抛 NullPointerException:
- 而实际业务中,数据库字段可能为空、API 返回值可能为 null,HashMap 允许一个 null 键和任意 null 值,更贴合现实场景
- 没有提供像
computeIfAbsent、merge这类原子复合操作,开发者只能手动加锁实现,易出错
迭代器不 fail-fast,隐患难察觉
Hashtable 使用 Enumeration 而非 Iterator,且不支持 fail-fast:
立即学习“Java免费学习笔记(深入)”;
- 遍历时若其他线程修改了 Map,不会立即报错,而是可能读到脏数据、丢失更新,甚至出现无限循环(尤其在链表成环时)
- HashMap 和 ConcurrentHashMap 的迭代器都能在检测到并发修改时快速失败(抛
ConcurrentModificationException),利于问题定位
底层没进化,长期技术债
对比现代哈希结构:
- HashMap(JDK 8+)和 ConcurrentHashMap(JDK 8+)在链表过长时自动转红黑树,查询从 O(n) 优化到 O(log n)
- Hashtable 始终只用数组 + 单向链表,极端哈希碰撞下性能急剧恶化
- 扩容策略原始:容量从 11 开始,每次变为
2n+1,无法保证 2 的幂次方,影响位运算取模效率
现在该用什么?单线程场景选 HashMap;需要线程安全,直接用 ConcurrentHashMap——它用 CAS + 桶级锁(JDK 8 后是头结点 synchronized),读写高度并发,还内置原子操作。Hashtable 已无不可替代的价值。


















