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 来保证并发操作的安全性,并且引入了红黑树来提高哈希冲突时的查找效率。
 
                    
                     
                    
                 
                    
                 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号