Java里HashMap和Hashtable有什么区别_JavaMap线程安全对比

HashMap非线程安全且支持null键值,Hashtable线程安全但已弃用、不支持null、性能差;推荐使用ConcurrentHashMap,其分段锁/CAS机制兼顾安全与高性能。

HashMap 不是线程安全的,Hashtable 是线程安全的,但已基本被弃用。 这是最核心的区别。实际开发中,若需线程安全的哈希表,应优先考虑 ConcurrentHashMap,而不是 Hashtable。

线程安全性与同步机制

Hashtable 的所有 public 方法(如 put()get()size())都用 synchronized 修饰,整个对象一把锁,吞吐量低,扩展性差。HashMap 完全不加锁,多线程下可能引发死循环(JDK 7)、数据丢失或 get 返回 null 等问题。

  • Hashtable 同步开销大,高并发场景性能明显劣于 ConcurrentHashMap
  • HashMap 在多线程写入时即使只调用 put(),也可能因扩容导致链表成环(JDK 7),引发 CPU 100%
  • JDK 8 中 HashMap 扩容改用红黑树和更安全的迁移逻辑,但仍不保证线程安全

Null 键与 Null 值支持

HashMap 允许一个 null 键和任意多个 null 值;Hashtable 不允许任何 null 键或 null 值,否则抛出 NullPointerException

  • 这使得 HashMap 更灵活,适合缓存、配置映射等常见场景
  • Hashtable 的严格限制在现代 Java 开发中反而成了负

    担,缺乏实用性

继承体系与接口实现

两者都实现了 Map 接口,但历史渊源不同:Hashtable 是 JDK 1.0 就存在的类,继承自已废弃的 Dictionary 抽象类;HashMap 是 JDK 1.2 引入的,属于 Java 集合框架(Collections Framework)一员,设计更规范、API 更统一。

  • Hashtable 有遗留方法如 elements()keys(),返回的是 Enumeration,而 HashMap 统一使用 Iterator
  • HashMap 支持函数式操作(如 computeIfAbsent()),Hashtable 完全不支持

替代方案:ConcurrentHashMap 才是正解

从 JDK 5 开始,ConcurrentHashMap 提供了更精细的并发控制(分段锁 → JDK 8 改为 CAS + synchronized 操作桶节点),兼顾线程安全与高性能。

  • 支持高并发读写,读操作完全无锁
  • 允许 null 值(但不允许 null 键),行为更接近 HashMap
  • 提供原子复合操作,如 putIfAbsent()compute(),避免外部同步