JJava 知识库
JAVA INTERVIEW

高频面试题

Java集合进阶约 2 分钟

你们用 ConcurrentHashMap 做过本地缓存或并发统计吗?它怎么保证并发安全,使用时还要注意什么?

参考回答约 2 分钟 · 口语表达
我的判断

ConcurrentHashMap 适合并发读写和单 key 原子更新,但它不是带过期、容量控制和加载保护的完整缓存。

我们会用它保存生命周期明确、规模可控的本地路由表,或者做短周期并发统计。读取通常不加全局锁,更新通过 CAS 和桶级同步控制竞争;计数会用 computemerge,热点统计则用 LongAdder,避免“先 get 再 put”这种复合操作丢更新。

counts.computeIfAbsent(key, ignored -> new LongAdder()).increment();

computeIfAbsent 的加载函数不能做慢 RPC,也不能递归修改同一个 key,否则会把竞争和故障放大。多个 key 之间的一致性它也保证不了,这时需要显式锁、不可变快照或重新设计状态边界。

如果需求包含 TTL、最大容量、淘汰、刷新和防缓存击穿,我会直接用 Caffeine,而不是在 ConcurrentHashMap 外再拼一套定时清理。上线后重点看 key 数、命中率、加载耗时和堆占用。

容易答偏踩坑误区
  • 线程安全等于所有操作都原子。 containsKey 后再 put 仍然有竞态。
  • 在计算函数里调用慢下游。 同 key 请求会排队,故障时很容易拖垮线程。
  • 当成无限缓存。 没有容量和过期策略,最终会变成堆内存问题。