MST
星途 面试题库

面试题:Java中ConcurrentHashMap对Hashtable的高并发优化改进

对比Java的ConcurrentHashMap和Hashtable,详细阐述ConcurrentHashMap在高并发场景下相较于Hashtable做了哪些优化改进,这些改进是如何实现的。
32.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

线程安全机制

  • Hashtable
    • 实现方式:对几乎所有涉及修改数据结构的方法(如putgetremove等)都使用synchronized关键字进行同步,这意味着同一时间只有一个线程可以访问这些方法,通过锁住整个哈希表来保证线程安全。
    • 缺点:在高并发场景下,由于锁的粒度太大,会导致大量线程竞争同一把锁,从而造成性能瓶颈。
  • ConcurrentHashMap
    • 实现方式:在Java 1.7及之前版本,采用分段锁(Segment)机制。每个Segment独立加锁,不同Segment之间的操作可以并发执行。比如在put操作时,只需要锁住当前元素对应的Segment,而不是整个哈希表。在Java 8及之后版本,摒弃了分段锁机制,采用Node数组 + 链表 + 红黑树的数据结构,并使用CAS(Compare - and - Swap)算法和synchronized关键字结合的方式实现线程安全。CAS用于更新一些基本操作,而synchronized则主要用于锁住链表头节点或红黑树的根节点,锁的粒度更细。
    • 优点:大大提高了并发性能,允许多个线程同时访问不同部分的数据,减少了线程竞争。

迭代器

  • Hashtable
    • 实现方式:当使用Iterator遍历Hashtable时,如果在遍历过程中其他线程对Hashtable进行了修改(增、删、改操作),会抛出ConcurrentModificationException异常,即采用快速失败(fail - fast)机制。
    • 缺点:这种机制在高并发场景下可能会导致遍历过程频繁失败,影响程序的正常执行。
  • ConcurrentHashMap
    • 实现方式:其迭代器采用弱一致性(weakly consistent)机制。在遍历过程中,允许其他线程对ConcurrentHashMap进行修改,迭代器能感知到部分修改,但不会抛出ConcurrentModificationException异常。迭代器遍历的是创建迭代器时哈希表的快照,而在遍历过程中新增的元素可能不会被遍历到,删除和修改的元素则会根据具体情况有不同表现。
    • 优点:在高并发环境下,迭代操作不会因为其他线程的修改而频繁失败,保证了遍历的相对稳定性,提高了并发性能。

性能优化

  • Hashtable
    • 性能表现:由于锁粒度大,在高并发场景下,大量线程竞争锁,导致线程频繁阻塞和唤醒,上下文切换开销大,从而性能较低。
  • ConcurrentHashMap
    • 性能表现:通过更细粒度的锁机制和CAS操作,减少了线程竞争,降低了上下文切换开销,提高了并发读写性能。例如在Java 8中,当链表长度超过阈值(默认为8)时会将链表转换为红黑树,提高了查找性能,进一步优化了高并发场景下的整体性能。