外观
如何理解ConcurrentHashMap 与复合操作?
标准回答
ConcurrentHashMap 支持并发访问,但先 get、判断、再 put 的组合仍可能竞态。需要使用 putIfAbsent、compute 等合适原子操作,或在更大业务范围使用锁与状态设计。现代实现不能简单概括为所有版本都固定采用分段锁。
计算函数应短且避免不必要的外部阻塞,否则可能扩大同类更新的等待。容器保证也不能保护其值对象内部任意可变字段;Map 线程安全并不意味着放入其中的对象也自动安全。
读多写少的监听列表可以考虑快照或 CopyOnWrite 类结构,代价是修改时复制和额外内存。更新频繁、集合很大或迭代需要即时反映变化时,要重新选择。并发容器的价值是明确可见性与原子边界,不是消除所有锁。
追问与回答
使用 volatile Map 可以保护内部 put 吗
volatile 主要影响引用的读写可见性,不把对象内部复合操作变成线程安全。
如何实现同键只初始化一次
可以原子登记一个 Future 或受控状态,再在锁外执行昂贵工作,并处理失败移除、取消与重试;不要在全局锁内初始化所有键。
易混淆点
- 用了并发 Map 就认为所有业务检查与更新已经原子。
参考资料
内容来源
- Android 与 AI 工程 Wiki · 原条目
q194