
核心清理机制1.惰性清理Lazy EvictionTimedCacheString, Object cache new TimedCache(1000); // 默认过期时间1秒 cache.put(key1, value1); // 在get时检查是否过期 Object value cache.get(key1); // 如果已过期返回null并从map中移除每次调用get()或containsKey()时会检查该键是否过期如果过期则移除。2.定期清理Schedule PruneTimedCacheString, Object cache new TimedCache(1000); cache.schedulePrune(1000); // 启动定时清理每1000ms执行一次通过调用schedulePrune()方法启动定时清理任务定期扫描并移除过期项。回到顶部 使用示例示例1基本使用不自动清理import cn.hutool.cache.impl.TimedCache; public class TimedCacheExample1 { public static void main(String[] args) throws InterruptedException { // 创建缓存默认过期时间1000ms TimedCacheString, String cache new TimedCache(1000); // 放入数据 cache.put(key1, value1); // 立即获取 System.out.println(立即获取 cache.get(key1)); // 输出: value1 // 等待1.1秒 Thread.sleep(1100); // 过期后获取 System.out.println(1.1秒后获取 cache.get(key1)); // 输出: null // 注意此时key1会从map中移除 // 检查大小 System.out.println(缓存大小 cache.size()); // 输出: 0 } }示例2启动定时清理import cn.hutool.cache.impl.TimedCache; public class TimedCacheExample2 { public static void main(String[] args) throws InterruptedException { // 创建缓存默认过期时间1000ms TimedCacheString, String cache new TimedCache(1000); // 启动定时清理每500ms执行一次 cache.schedulePrune(500); cache.put(key1, value1); cache.put(key2, value2, 2000); // 单独设置过期时间2000ms System.out.println(初始大小 cache.size()); // 输出: 2 Thread.sleep(1100); System.out.println(1.1秒后大小 cache.size()); // 输出: 1key1被清理 Thread.sleep(1000); System.out.println(2.1秒后大小 cache.size()); // 输出: 0key2被清理 // 关闭定时清理 cache.cancelPruneSchedule(); } }回到顶部⚡ 清理时机总结清理类型触发条件清理范围是否立即生效惰性清理调用get()、containsKey()等方法只检查被访问的key是定时清理定时任务触发需手动调用schedulePrune()所有过期key是容量清理达到缓存容量上限最近最少使用的过期项是回到顶部 源码解析查看TimedCache源码的关键方法1.检查过期并移除的方法// 在get操作时会调用 public V get(K key, boolean isUpdateLastAccess) { CacheObjK, V co getWithoutLock(key); if (co null) { missCount.increment(); return null; } // 检查是否过期 if (co.isExpired()) { // 过期则移除 remove(key, true); missCount.increment(); return null; } // ... 返回缓存值 }2.定时清理任务public void schedulePrune(long delay) { this.pruneTimer.schedule(new TimerTask() { Override public void run() { pruneCache(); // 执行清理 } }, delay, delay); }回到顶部 使用建议1.根据场景选择清理策略// 场景1低频率访问使用惰性清理即可 TimedCacheString, Object cache1 new TimedCache(5000); // 场景2高频率访问需要定时清理避免内存泄漏 TimedCacheString, Object cache2 new TimedCache(5000); cache2.schedulePrune(1000); // 每1秒清理一次 // 场景3需要严格内存控制 TimedCacheString, Object cache3 new TimedCache(5000, 1000); // 容量限制1000 cache3.schedulePrune(500);2.合理设置过期时间// 为不同数据设置不同过期时间 TimedCacheString, Object cache new TimedCache(); // 默认过期时间5秒 cache.setDefaultTimeout(5000); // 特定key设置特定过期时间 cache.put(session_token, abc123, 30 * 60 * 1000); // 30分钟 cache.put(captcha, 1234, 5 * 60 * 1000); // 5分钟 cache.put(page_cache, html.../html, 1000); // 1秒3.监听器支持TimedCacheString, Object cache new TimedCache(1000); cache.setListener(new CacheListenerString, Object() { Override public void onRemove(String key, Object value) { System.out.println(Key被移除 key 值 value); } });回到顶部⚠️ 注意事项定时清理需手动启动schedulePrune()必须显式调用才会启动定时清理内存泄漏风险如果不调用schedulePrune()且从不访问过期key这些key会一直占用内存Timer的内存泄漏定时清理使用Timer如果缓存对象被GC定时任务不会自动取消性能考虑定时清理间隔不宜过短特别是缓存项很多时回到顶部 完整生命周期示例