2025-04-02 18:28:46 +08:00
|
|
|
|
# ConcurrentHashMap 不同JDK版本的实现对比
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
## 1. 数据结构
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
- **JDK1.7**:
|
|
|
|
|
- 使用 `Segment(分段锁) + HashEntry数组 + 链表` 的数据结构
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
- **JDK1.8及之后**:
|
|
|
|
|
- 使用 `数组 + 链表/红黑树` 的数据结构(与HashMap类似)
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
## 2. 锁的类型与宽度
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
- **JDK1.7**:
|
|
|
|
|
- 分段锁(Segment)继承了 `ReentrantLock`
|
|
|
|
|
- Segment容量默认16,不会扩容 → 默认支持16个线程并发访问
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
- **JDK1.8**:
|
|
|
|
|
- 使用 `synchronized + CAS` 保证线程安全
|
|
|
|
|
- 空节点:通过CAS添加
|
|
|
|
|
- 非空节点:通过synchronized加锁
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
## 3. 渐进式扩容(JDK1.8+)
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
- **触发条件**:元素数量 ≥ `数组容量 × 负载因子(默认0.75)`
|
|
|
|
|
- **扩容过程**:
|
|
|
|
|
1. 创建2倍大小的新数组
|
|
|
|
|
2. 线程操作数据时,逐步迁移旧数组数据到新数组
|
|
|
|
|
3. 使用 `transferIndex` 标记迁移进度
|
|
|
|
|
4. 直到旧数组数据完全迁移完成
|
2025-03-24 16:04:56 +08:00
|
|
|
|
|
2025-04-02 18:28:46 +08:00
|
|
|
|
### 关键改进点:
|
|
|
|
|
- 降低大数据量扩容时的性能开销
|
|
|
|
|
- 允许读写操作与扩容并发进行
|