当前位置: 首页 > news >正文

Hutool 的 `TimedCache` 到期会自动清理吗? ——————hutool cache的“惰性清理“和“定期清理“

核心清理机制

1.惰性清理(Lazy Eviction)

TimedCache<String, Object> cache = new TimedCache<>(1000); // 默认过期时间1秒 cache.put("key1", "value1"); // 在get时检查是否过期 Object value = cache.get("key1"); // 如果已过期,返回null并从map中移除

每次调用get()containsKey()时,会检查该键是否过期,如果过期则移除。

2.定期清理(Schedule Prune)

TimedCache<String, 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 TimedCache<String, 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 TimedCache<String, 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()); // 输出: 1(key1被清理) Thread.sleep(1000); System.out.println("2.1秒后大小:" + cache.size()); // 输出: 0(key2被清理) // 关闭定时清理 cache.cancelPruneSchedule(); } }

回到顶部

⚡ 清理时机总结

清理类型触发条件清理范围是否立即生效
惰性清理调用get()containsKey()等方法只检查被访问的key
定时清理定时任务触发(需手动调用schedulePrune()所有过期key
容量清理达到缓存容量上限最近最少使用的过期项

回到顶部

📊 源码解析

查看TimedCache源码的关键方法:

1.检查过期并移除的方法

// 在get操作时会调用 public V get(K key, boolean isUpdateLastAccess) { CacheObj<K, 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:低频率访问,使用惰性清理即可 TimedCache<String, Object> cache1 = new TimedCache<>(5000); // 场景2:高频率访问,需要定时清理避免内存泄漏 TimedCache<String, Object> cache2 = new TimedCache<>(5000); cache2.schedulePrune(1000); // 每1秒清理一次 // 场景3:需要严格内存控制 TimedCache<String, Object> cache3 = new TimedCache<>(5000, 1000); // 容量限制1000 cache3.schedulePrune(500);

2.合理设置过期时间

// 为不同数据设置不同过期时间 TimedCache<String, 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.监听器支持

TimedCache<String, Object> cache = new TimedCache<>(1000); cache.setListener(new CacheListener<String, Object>() { @Override public void onRemove(String key, Object value) { System.out.println("Key被移除:" + key + ",值:" + value); } });

回到顶部

⚠️ 注意事项

  1. 定时清理需手动启动schedulePrune()必须显式调用才会启动定时清理
  2. 内存泄漏风险:如果不调用schedulePrune()且从不访问过期key,这些key会一直占用内存
  3. Timer的内存泄漏:定时清理使用Timer,如果缓存对象被GC,定时任务不会自动取消
  4. 性能考虑:定时清理间隔不宜过短,特别是缓存项很多时

回到顶部

🔄 完整生命周期示例

http://www.jsqmd.com/news/1093028/

相关文章:

  • 递归函数Recursive Function
  • 如何评价GLM-5.2?
  • 联邦学习侧信道攻击:FLARE框架解析与防御
  • 成功企业的衰亡密码:从“看不见的癌症”到真正的长期主义
  • agency-agents-zh大更新:一句话,让 216个 AI 专家组队替你干活,上线桌面端和web端了!已开源
  • 每日一个开源项目(第145篇):Trellis - 把项目记忆、规范和任务上下文持久化进代码仓库
  • 2026好用的视频去水印工具电脑手机推荐,免费无广告精选
  • 量子约束优化搜索框架CBQS解析与应用
  • 计算机毕业设计之基于SSM框架技术的超市货品销售预警平台的设计与实现
  • 别让AI一直“读心“:冲突触发式心智理论的因果模型
  • 内网 Web 服务断外网后白屏卡顿?全链路排查手册与根治方案
  • 盘点优质虚拟资源货源,这家老牌平台凭什么让我死磕
  • 女性站长学SEO比男性更有优势吗?
  • 数据分析中常用的回归分析是什么?它的应用场景有哪些?
  • BCH码介绍
  • 《HarmonyOS技术精讲-Core File Kit(文件基础服务)》第1篇:文件沙箱概念与核心架构
  • 这份榜单够用!2026年最流行AI论文平台榜单,免费高效产出合规稿
  • 跳出空白文档内耗:Paperxie 毕业论文智能写作,搭建分层式学术创作闭环
  • 2026上海专业招商场地推荐:选址就该这样选
  • 超小尺寸,超高算力:明远智睿RV1126B开发板全面评测
  • 基于大数据爬虫+Hadoop+Spark的食品数据分析预测可视化系统
  • 2026互联网一线大厂Java八股文面试题汇总
  • 收藏 | 程序员小白也能懂的大模型RAG实践:从Demo到生产环境的8大难点解析
  • 普通漏洞和零日漏洞(zero-day vulnerability)区别
  • 网约车后端实战:Gin 网关下的实时订单系统设计与踩坑
  • 拒绝急于求成:2026年GEO优化周期如何科学规划与预期管理
  • 因果性幻觉:A和B之间隔着一万个变量,也能被讲成因果关系。
  • 大麦抢票协议算法
  • Windows 11卡顿烦恼?这款开源工具3分钟还你流畅系统体验
  • 董事会要求AI回报,但团队尚未做好准备