Skip to content

HashMap线程安全吗,如何保证线程安全,使用什么集合

约 505 字大约 2 分钟

Java基础美团

2025-04-14

⭐ 题目日期:

美团 - 2025/4/4

📝 题解:

HashMap 在 Java 中不是线程安全的。在多线程环境下,如果多个线程同时对 HashMap 进行修改(如添加、删除或扩容操作),可能会导致数据不一致、死循环或其他未定义行为。以下是保证线程安全的常用方法及对应的集合类:


一、如何保证线程安全?

1. 使用 Collections.synchronizedMap

Map<K, V> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
  • 原理:通过给所有方法添加 synchronized 关键字,锁住整个 Map 实例。
  • 缺点:锁粒度粗,高并发时性能较差。

2. 使用 ConcurrentHashMap

Map<K, V> concurrentMap = new ConcurrentHashMap<>();
  • 原理
    • Java 7:分段锁(Segment),将数据分成多个段,每段独立加锁,提高并发度。
    • Java 8+:改用 CAS(Compare-And-Swap)和 synchronized 锁单个桶(Node),进一步优化并发性能。
  • 优点:高并发场景下性能优异,推荐使用。

3. 使用 Hashtable(不推荐)

Map<K, V> hashtable = new Hashtable<>();
  • 原理:所有方法通过 synchronized 加锁,锁住整个实例。
  • 缺点:性能差,已逐渐被 ConcurrentHashMap 取代。

二、如何选择线程安全集合?

集合类适用场景性能推荐度
ConcurrentHashMap高并发读写、大规模数据★★★★★
Collections.synchronizedMap低并发、简单同步需求中低★★☆
Hashtable遗留代码兼容(不推荐新项目使用)★☆☆

三、关键区别总结

  1. 锁粒度
    • HashtablesynchronizedMap 锁整个实例。
    • ConcurrentHashMap 锁单个桶(Java 8+)或分段(Java 7),锁粒度更细。
  2. 性能
    • ConcurrentHashMap > synchronizedMap > Hashtable
  3. 适用场景
    • 优先选择 ConcurrentHashMap,几乎覆盖所有需要线程安全 Map 的场景。

四、其他线程安全集合

  • CopyOnWriteArrayList:读多写少的线程安全 List。
  • ConcurrentLinkedQueue:高并发队列。
  • BlockingQueue 实现类:如 LinkedBlockingQueue,用于生产者-消费者模型。

总结:在多线程环境中,优先使用 ConcurrentHashMap,避免使用 Hashtable 和手动同步的 synchronizedMap