ConcurrentHashMap面试(背会)

ConcurrentHashMap面试

ConcurrentHashMap是 Java 中用于在多线程环境下高效使用的哈希表实现,在不同的 Java 版本中其底层数据结构有所不同,下面为你分别介绍:

Java 7 中的 ConcurrentHashMap

在 Java 7 里,ConcurrentHashMap 的底层数据结构由分段锁(Segment)和哈希表(HashEntry)构成。

  • 分段锁(Segment)ConcurrentHashMap 把整个哈希表划分成多个段(Segment),每个段都相当于一个小的 HashMap,并且拥有自己的锁。默认情况下有 16 个段,这意味着最多可以支持 16 个线程同时并发访问。
  • 哈希表(HashEntry):每个段内部是一个由 HashEntry 数组组成的哈希表。HashEntry 是一个链表节点,包含键、值、哈希值和指向下一个节点的引用。当发生哈希冲突时,新的元素会被添加到链表的头部。

下面是一个简单的示意图:

ConcurrentHashMap
├── Segment[0]
│   ├── HashEntry -> HashEntry -> ...
│   └── ...
├── Segment[1]
│   ├── HashEntry -> HashEntry -> ...
│   └── ...
└── ...

Java 8 中的 ConcurrentHashMap

Java 8 对 ConcurrentHashMap 进行了较大的改动,摒弃了分段锁机制,采用了 CAS(Compare-And-Swap)和 synchronized 来保证并发操作的安全性,底层数据结构为数组 + 链表 + 红黑树。

  • 数组(Node [])ConcurrentHashMap 的基础存储结构是一个 Node 类型的数组,每个 Node 包含键、值、哈希值和指向下一个节点的引用。
  • 链表:当发生哈希冲突时,新的元素会被添加到链表的尾部。如果链表长度超过一定阈值(默认为 8),链表会转换为红黑树。
  • 红黑树:红黑树是一种自平衡的二叉搜索树,能够在 O (log n) 的时间复杂度内完成查找、插入和删除操作。当链表长度过长时,将链表转换为红黑树可以提高查找效率。

下面是一个简单的示意图:

ConcurrentHashMap
├── Node[]
│   ├── Node -> Node -> ... (链表)
│   ├── TreeNode -> TreeNode -> ... (红黑树)
│   └── ...

综上所述,Java 7 中的 ConcurrentHashMap 通过分段锁实现并发控制,而 Java 8 则使用 CAS 和 synchronized 来保证并发操作的安全性,并且引入了红黑树来提高哈希冲突时的查找效率。

posted on 2025-04-12 16:19  ~码铃薯~  阅读(34)  评论(0)    收藏  举报

导航