用System.currentTimeMillis()控制缓存生命周期本质是记录写入时间戳并实时比对当前时间判断过期,轻量无依赖但需注意时钟漂移、精度及线程安全;示例使用ConcurrentHashMap实现put/get与惰性清理。

用 System.currentTimeMillis() 控制缓存生命周期,本质是记录“写入时间”,后续通过对比当前时间与写入时间的差值,判断是否过期。它轻量、无依赖,适合简单场景,但需注意精度、时钟漂移和线程安全等细节。
缓存写入时记录时间戳
每次存入数据,同时保存当前毫秒时间戳(如 long 型字段或 Map 中额外 key):
- 可封装为一个简单缓存项类,例如:
class CacheEntry<T> { T data; long createTime; long expireAfterMs; } - 写入缓存时调用
System.currentTimeMillis()赋值createTime,并设定预期有效期(如 5 分钟 →expireAfterMs = 5 * 60 * 1000) - 避免在构造或序列化阶段“预计算”时间戳,必须在真正写入那一刻获取,否则可能因调度延迟导致偏差
读取时动态判断是否过期
每次 get 操作不依赖后台清理,而是实时比对:
- 取出缓存项后,计算:
System.currentTimeMillis() - entry.createTime > entry.expireAfterMs - 若为 true,视为过期,可返回 null、触发 reload,或抛出自定义异常
- 不建议在 get 中自动删除过期项(除非明确需要清理),因为并发读可能导致重复 reload;更稳妥的做法是标记+惰性淘汰
注意系统时钟影响
System.currentTimeMillis() 依赖操作系统时钟,存在两类风险:
- 手动或 NTP 同步导致时间跳变:比如时钟被向后校准 1 秒,所有刚写入的缓存瞬间“变老”;向前提前则延长实际有效期
- 高频率调用下,连续两次调用可能返回相同值(尤其在 Windows 上),虽不影响过期逻辑,但不利于精确调试
- 对强一致性要求高的场景,可考虑
System.nanoTime()做相对计时(仅限单次请求内耗时统计),但不能替代绝对时间判断
轻量级实现示例(无第三方库)
一个线程安全的简易内存缓存片段:
private final Map<String, CacheEntry<Object>> cache = new ConcurrentHashMap<>();
<p>public void put(String key, Object value, long expireMs) {
long now = System.currentTimeMillis();
cache.put(key, new CacheEntry<>(value, now, expireMs));
}</p><p>public Object get(String key) {
CacheEntry<Object> entry = cache.get(key);
if (entry == null) return null;
if (System.currentTimeMillis() - entry.createTime > entry.expireAfterMs) {
cache.remove(key); // 惰性清理
return null;
}
return entry.data;
}</p>

















