Java TimedCache 带时间缓存工具类详解使用
简述
我们在工作中会碰到需要使用带过期时间的缓存场景。但是使用redis有太重了,毕竟缓存的数据很小,放在内存够够的。hutools提供了TimedCache时间缓存工具,可以实现该场景。下面使用到该组件,并为了适配工作场景,对该工具类做优化升级。
Maven依赖
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.6</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency>
简单使用
不多说了,上代码。
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.hutool.core.thread.ThreadUtil; /** @Author huyi @Date 2021/10/12 17:00 @Description: */ public class TimedCacheUtils { private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000); static { /** 每5ms检查一次过期 */ TIMED_CACHE.schedulePrune(5); } /** * 存入键值对,提供消逝时间 * * @param key * @param value * @param timeout */ public static void put(String key, String value, Long timeout) { /** 设置消逝时间 */ TIMED_CACHE.put(key, value, timeout); } /** * 每次重新get一次缓存,均会重新刷新消逝时间 * @param key * @return */ public static String get(String key) { return TIMED_CACHE.get(key); } public static void main(String[] args) { put("haha", "1", 3000L); ThreadUtil.sleep(2000); // if (TIMED_CACHE.containsKey("haha")) { // System.out.println("aa"); // } System.out.println("第1次结果:" + get("haha")); ThreadUtil.sleep(2000); System.out.println("第2次结果:" + get("haha")); ThreadUtil.sleep(5000); System.out.println("第3次结果:" + get("haha")); // 取消定时清理 TIMED_CACHE.cancelPruneSchedule(); } }
首先我们看一下执行的效果
说明:
1、设置的超时时间为3000毫秒,所以第一次打印在2秒钟,所以可以获取到值。
2、因为第一次打印调用了get方法,刷新了过期时间,所以依然可以获取到值。
3、第三次打印在5秒后,所以已经过期,无法获取到值,打印null。
那么,需要知道是否缓存还在可以使用containsKey方法。如下:
put("haha", "1", 3000L); ThreadUtil.sleep(2000); if (TIMED_CACHE.containsKey("haha")) { System.out.println("第1次结果:缓存存在"); } // System.out.println("第1次结果:" + get("haha")); ThreadUtil.sleep(2000); System.out.println("第2次结果:" + get("haha")); ThreadUtil.sleep(5000); System.out.println("第3次结果:" + get("haha")); // 取消定时清理 TIMED_CACHE.cancelPruneSchedule();
执行结果如下:
工具优化-监听过期、增加回调
我们在使用TimedCache会发现,一旦缓存过期我们并不能立马知道,很多工作场景中需要对缓存做监听回调。所以我升级了一下该工具类。
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.hutool.core.thread.ThreadUtil; import com.google.common.util.concurrent.*; import org.checkerframework.checker.nullness.qual.Nullable; import java.text.MessageFormat; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; /** @Author huyi @Date 2021/10/12 10:57 @Description: 时间缓存工具 */ public class TimedCacheUtils { private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000); /** 线程池 */ private static final ExecutorService executorService = Executors.newCachedThreadPool(); private static final ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService); /** 回调方法映射 */ private static ConcurrentHashMap<String, Consumer<String>> callbackMap; /** * 存入键值对,添加过期时间,和消费回调 * * @param key * @param timeout * @param consumer */ public static void put(String key, String value, Long timeout, Consumer<String> consumer) { TIMED_CACHE.put(key, value, timeout); addListen(key, consumer); } /** * 获取缓存值 * * @param key * @return */ public static String get(String key) { return TIMED_CACHE.get(key); } /** * 删除缓存和回调映射 * * @param key */ public static void remove(String key) { callbackMap.remove(key); TIMED_CACHE.remove(key); } /** * 添加监听器 * * @param key * @param consumer */ public static void addListen(String key, Consumer<String> consumer) { ListenableFuture<String> listenableFuture = listeningExecutorService.submit( () -> { while (TIMED_CACHE.containsKey(key)) { ThreadUtil.sleep(500); } return key; }); Futures.addCallback( listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(@Nullable String s) { consumer.accept(s); } @Override public void onFailure(Throwable throwable) { throwable.printStackTrace(); } }, listeningExecutorService); } public static void main(String[] args) { put("haha", "1", 3000L, x -> System.out.println(MessageFormat.format("[{0}] - 缓存消逝", x))); ThreadUtil.sleep(2000); System.out.println(get("haha")); ThreadUtil.sleep(2000); System.out.println(get("haha")); ThreadUtil.sleep(5000); System.out.println(get("haha")); // 关闭监听线程池 listeningExecutorService.shutdown(); } }
执行结果:
说明:
1、可以看到监听到缓存过期,并进行了回调。
总结
具体的工具类使用场景,因项目而异,大家看着来。
如果本文对你有帮助,请点个赞支持一下吧。
到此这篇关于Java TimedCache 带时间缓存工具类详解使用的文章就介绍到这了,更多相关Java TimedCache内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://huyi-aliang.blog.csdn.net/article/details/120727999
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20- 这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19
- 在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13