用system.currenttimemillis()实现缓存过期的核心是记录写入时间戳,读取时用当前时间减去时间戳判断是否超过expiremillis;需同步更新时间戳,注意时钟回拨、线程安全及精度限制。

用 System.currentTimeMillis() 计算时间差来控制缓存失效,核心是:**记录缓存写入时间戳,每次读取时用当前时间减去它,判断是否超过预设有效期**。这种方式轻量、无依赖,适合简单场景,但要注意精度、时钟漂移和线程安全等细节。
1. 基础实现:时间戳 + 有效期判断
缓存项(比如一个字符串值)附带一个 long timestamp 字段,表示写入时刻。读取时检查:
- 当前时间
System.currentTimeMillis() - 缓存时间戳
cachedTime - 过期时长(如 5 分钟 =
5 * 60 * 1000L)
判断逻辑:currentTime - cachedTime > expireMillis,成立则缓存已失效,需重新加载。
2. 示例代码:简易内存缓存封装
以下是一个线程安全的简单实现(使用 ConcurrentHashMap):
public class SimpleCache<k v> {
private final ConcurrentHashMap<k cacheentry>> cache = new ConcurrentHashMap();
private final long expireMillis;
<pre class="brush:java;toolbar:false;">public SimpleCache(long expireMillis) {
this.expireMillis = expireMillis;
}
public V get(K key) {
CacheEntry<V> entry = cache.get(key);
if (entry == null) return null;
if (System.currentTimeMillis() - entry.timestamp > expireMillis) {
cache.remove(key); // 过期后主动清理
return null;
}
return entry.value;
}
public void put(K key, V value) {
cache.put(key, new CacheEntry<>(value));
}
static class CacheEntry<V> {
final V value;
final long timestamp;
CacheEntry(V value) {
this.value = value;
this.timestamp = System.currentTimeMillis();
}
}
}
// 使用:SimpleCache
3. 注意事项与常见坑
-
系统时钟可能被手动调整:若服务器时间回拨,会导致缓存提前失效;NTP 同步也可能造成跳变。生产环境建议搭配
System.nanoTime()做相对计时(但无法跨 JVM 使用) - 毫秒级精度足够,但别用于亚秒级控制:比如要求“10 秒整”过期,实际误差在几毫秒内,可接受;但不要指望它精确到 100ms 级别
-
避免在循环或高频调用中反复调用
currentTimeMillis():虽然开销极小,但极端场景下可缓存一次时间值复用(注意语义是否允许) - 清除策略建议“惰性+主动”结合:读取时检查(惰性),也可另起线程定期扫描清理(主动),防止长期不访问的脏数据堆积
4. 和其他方案的对比参考
相比 Guava Cache 或 Caffeine:
- 优点:零依赖、逻辑透明、内存占用低
- 缺点:不支持最大容量驱逐、LRU/LFU、自动刷新、统计监控等高级能力
- 适用场景:配置类、权限规则、短时效基础数据等变化不频繁、结构简单的缓存
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











