标准答案
- 并发容器保证其公开操作的并发语义,不等于业务多步流程自动原子。
- putIfAbsent、computeIfAbsent 和 merge 可把常见的查改写组合成容器级原子动作。
- 计算函数不应执行长时间阻塞或重入同一 Map 的复杂操作。
- 迭代器通常弱一致,不应把遍历快照当成严格事务视图。
题目解析
ConcurrentHashMap 保证的是容器方法的并发语义,不会把多个业务步骤自动合成事务。containsKey 后再 put 仍存在竞态,应使用 putIfAbsent、compute 或 merge 表达单次原子组合。
compute 函数应短小、无副作用、可重复调用,不要在其中执行慢 HTTP、数据库操作或重入同一 Map 的复杂逻辑,否则会延长内部协调并造成死锁或吞吐下降。
弱一致迭代器允许遍历期间发生变化,适合观察或近似统计,不是严格快照。需要一致视图时应使用快照、锁或数据库事务。
常见误区
- 误区:containsKey 后再 put。改正:使用 putIfAbsent 或 computeIfAbsent,必要时把业务约束放到数据库。
- 误区:在 compute 函数里调用慢外部服务。改正:只做快速本地计算,外部调用移出 Map 的原子区。
- 误区:认为遍历期间一定看不到任何变化。改正:理解弱一致迭代语义,需要严格快照时使用更高层同步。