ConcurrentHashMap 为什么适合并发场景
ConcurrentHashMap 为什么在并发场景下更合适,背后涉及哪些实现细节。从 Java 7 到 Java 8,它的实现发生了很大变化。本文结合实际代码讲清楚这些变化和设计思想。
基本使用
Map<Long, String> userMap = new HashMap<>(); |
HashMap 会先根据 key 的 hash 值定位数组下标。如果多个 key 落在同一个位置,就会形成冲突,Java 8 以后冲突链较长时会转成红黑树。
扩容为什么要注意
默认负载因子是 0.75。元素数量超过阈值时,HashMap 会扩容,数组容量通常变成原来的 2 倍。扩容需要重新分布元素,所以如果你大概知道数据量,建议初始化容量:
Map<Long, String> userMap = new HashMap<>(1024); |
常见坑
- HashMap 不是线程安全的,多线程写入要用 ConcurrentHashMap。
- 自定义对象作为 key 时,要正确重写 equals 和 hashCode。
- 不要在遍历 Map 时直接修改结构,必要时用迭代器或收集后再处理。
核心要点
Java 7 使用分段锁,Java 8 使用 CAS + synchronized
锁粒度从段级别降到了节点级别
使用红黑树优化链表的查询性能
支持原子操作,如 putIfAbsent、computeIfAbsent
总结
ConcurrentHashMap 是并发编程中常用的数据结构,理解它的实现细节有助于更好地使用它。在实际项目中,选择合适的并发集合可以显著提升性能。