Python 官方文档:入门教程 => 点击学习
目录一、技术背景二、技术效果三、ExpiringMap3.1功能简介3.2源码3.3示例四、LoadinGCache4.1功能简介4.2示例4.3移除机制4.4其他五、HashMap
在实际的项目开发中,我们经常会使用到缓存中间件(如Redis、MemCache等)来帮助我们提高系统的可用性和健壮性。
但是很多时候如果项目比较简单,就没有必要为了使用缓存而专门引入Redis等等中间件来加重系统的复杂性。那么Java本身有没有好用的轻量级的缓存组件呢。
答案当然是有喽,而且方法不止一种。常见的解决方法有:ExpiringMap、LoadingCache及基于HashMap的封装三种。
GitHub地址
添加依赖(Maven)
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.8</version>
</dependency>
示例源码
public class ExpiringMapApp {
public static void main(String[] args) {
// maxSize: 设置最大值,添加第11个entry时,会导致第1个立马过期(即使没到过期时间)
// expiration:设置每个key有效时间10s, 如果key不设置过期时间,key永久有效。
// variableExpiration: 允许更新过期时间值,如果不设置variableExpiration,不允许后面更改过期时间,一旦执行更改过期时间操作会抛异常UnsupportedOperationException
// policy:
// CREATED: 只在put和replace方法清零过期时间
// ACCESSED: 在CREATED策略基础上增加, 在还没过期时get方法清零过期时间。
// 清零过期时间也就是重置过期时间,重新计算过期时间.
ExpiringMap<String, String> map = ExpiringMap.builder()
.maxSize(10)
.expiration(10, TimeUnit.SECONDS)
.variableExpiration().expirationPolicy(ExpirationPolicy.CREATED).build();
map.put("token", "lkj2412lj1412412nmlkjl2n34l23n4");
map.put("name", "管理员", 20000, TimeUnit.SECONDS);
// 模拟线程等待...
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("token ===> " + map.get("token"));
System.out.println("name ===> " + map.get("name"));
// 注意: 在创建map时,指定的那些参数如过期时间和过期策略都是全局的, 对map中添加的每一个entry都适用.
// 在put一个entry键值对时可以对当前entry 单独设置 过期时间、过期策略,只对当前这个entry有效.
}
}
运行结果
token ===> null
name ===> 管理员
注意
在创建map时,指定的那些参数如过期时间和过期策略都是全局的, 对map中添加的每一个entry都适用。
在put一个entry键值对时可以对当前entry 单独设置 过期时间、过期策略,只对当前这个entry有效.
特点:提供缓存回收机制,监控缓存加载/命中情况,灵活强大的功能,简单易上手的api。
源码
public class LoadingCacheApp {
public static void main(String[] args) throws Exception {
// maximumSize: 缓存池大小,在缓存项接近该大小时, Guava开始回收旧的缓存项
// expireAfterAccess: 设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程里面不定期维护)
// removalListener: 移除监听器,缓存项被移除时会触发的钩子
// recordStats: 开启Guava Cache的统计功能
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterAccess(10, TimeUnit.SECONDS)
.removalListener(new RemovalListener<String, String>() {
@Override
public void onRemoval(RemovalNotification<String, String> removalNotification) {
System.out.println("过时删除的钩子触发了... key ===> " + removalNotification.geTKEy());
}
})
.recordStats()
.build(new CacheLoader<String, String>() {
// 处理缓存键不存在缓存值时的处理逻辑
@Override
public String load(String key) throws Exception {
return "不存在的key";
}
});
cache.put("name", "小明");
cache.put("pwd", "112345");
// 模拟线程等待...
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("token ===> " + cache.get("name"));
System.out.println("name ===> " + cache.get("pwd"));
}
}
运行结果
过时删除的钩子触发了... key ===> name
token ===> 不存在的key
过时删除的钩子触发了... key ===> pwd
name ===> 不存在的key
guava做cache时候数据的移除分为被动移除和主动移除两种。
被动移除
主动移除
如果配置了移除监听器RemovalListener,则在所有移除的动作时会同步执行该listener下的逻辑。
如需改成异步,使用:RemovalListeners.asynchronous(RemovalListener, Executor).
CacheBuilder构建的缓存不会在特定时间自动执行清理和回收工作,也不会在某个缓存项过期后马上清理,它不会启动一个线程来进行缓存维护,因为首先线程相对较重,其次某些环境限制线程的创建。
它会在写操作时顺带做少量的维护工作,或者偶尔在读操作时做。当然,也可以创建自己的维护线程,以固定的时间间隔调用Cache.cleanUp()。
我们可以参考上面两个工具包的思路,自己封装一个可以设置过时时间的HashMap来实现我们想要的效果。
到此这篇关于Java如何设置过期时间的map的几种方法的文章就介绍到这了,更多相关Java 过期时间map内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Java如何设置过期时间的map的几种方法
本文链接: https://lsjlt.com/news/142700.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0