ConcurrentHashMap可实现线程安全内存缓存,需封装put/get/remove并嵌入过期时间戳校验;结合LinkedHashMap实现LRU淘汰;支持软/弱引用缓解内存压力;应提供配置管理、命中统计与生命周期控制。

用ConcurrentHashMap实现线程安全的内存缓存
Java内置的ConcurrentHashMap是构建轻量级内存缓存的理想选择。它天然支持高并发读写,避免了手动加锁的复杂性。缓存核心逻辑只需封装put、get、remove操作,并加入基础的过期判断——比如在value中嵌入过期时间戳,每次get时检查是否超时。
建议做法:
- 缓存key用String或自定义对象(需重写hashCode和equals)
- value可包装为内部类,如CachedValue
,包含data、createTime、expireAfterMillis三个字段 - get时先判空再校验过期,过期则remove并返回null,不自动刷新
- 避免在get中做耗时计算,保持响应在微秒级
添加LRU淘汰策略让缓存更可控
纯ConcurrentHashMap不会自动清理旧数据,容易导致内存泄漏。引入LinkedHashMap的accessOrder机制可轻松实现LRU(最近最少使用)淘汰。继承LinkedHashMap并重写removeEldestEntry方法,在size超过阈值时移除最久未访问项。
实际组合技巧:
立即学习“Java免费学习笔记(深入)”;
- 用ConcurrentHashMap做主存储,保证并发安全
- 用独立的LinkedHashMap仅维护访问顺序(读写时同步更新该map)
- 淘汰动作放在put后异步触发,或由定时任务定期清理
- 设置合理容量上限,例如默认1000条,避免无节制增长
支持软引用/弱引用缓解堆内存压力
当缓存数据较大(如图片缩略图、JSON解析结果),可考虑用SoftReference或WeakReference包装value。JVM在内存紧张时会自动回收这些引用指向的对象,降低OOM风险。
注意点:
- SoftReference适合“希望尽量保留”的场景,GC前优先保留
- WeakReference适合“随时可丢”的临时数据,GC时立即回收
- 使用引用类型后,get返回前必须判null,防止NPE
- 不建议对高频访问的小对象用引用包装,徒增GC开销
提供简易配置与生命周期管理
一个实用的缓存服务应支持启动初始化、运行时刷新、关闭清理。可通过静态内部类+双重检查锁实现单例;用ScheduledExecutorService执行定期过期扫描;关闭时遍历清空并释放资源。
关键设计建议:
- 构造时传入配置:最大容量、默认过期时间、是否启用LRU
- 暴露clear()、size()、stats()等运维友好方法
- 日志记录缓存命中率(可用AtomicLong统计hit/miss次数)
- 避免在finalize或ShutdownHook中做复杂操作,防止卡住JVM退出










