概述
高性能、低开销、零依赖性、线程安全的ConcurrentMap实现,一款基于内存可过期的map。
使用场景是介于redis和普通map之间,觉得redis过于重不想依赖redis,普通map又不自动过期。
1、支持设置map中key过一段时间自动过期,过期策略有按创建时间、按访问时间。
过期策略为ExpirationPolicy.CREATED时,
如果在过期前有更新(指有变化),过期时间会从新计算。
如果在过期前有更新(指值未变化),过期时间不会从新计算。
2、可设置maxSize,超出再次插入会从第一个值过期
3、 过期key监听,可实现多个监听
过期策略为ExpirationPolicy.CREATED
@Test
public void testCREATED() throws InterruptedException {
ExpiringMap<String, String> map = ExpiringMap.builder().expiration(3000, TimeUnit.MILLISECONDS).
expirationPolicy(ExpirationPolicy.CREATED)
.build();
map.put("testkey", "testValue");
log.info("map={}", JSONUtil.toJsonStr(map));
Thread.sleep(3000);
log.info("sleep map={}", JSONUtil.toJsonStr(map));
}
执行结果:
10:53:16.256 [main] INFO util.ExpiringMapTest - map={"testkey":"testValue"}
10:53:19.264 [main] INFO util.ExpiringMapTest - sleep map={}
过期策略为ExpirationPolicy.CREATED,过期前更新
@Test
public void testCREATED2() throws InterruptedException {
ExpiringMap<String, String> map = ExpiringMap.builder().expiration(5000, TimeUnit.MILLISECONDS).
expirationPolicy(ExpirationPolicy.CREATED)
.build();
map.put("testkey", "testValue2");
log.info("map={}", JSONUtil.toJsonStr(map));
Thread.sleep(4000);
map.put("testkey", "testValue3");
log.info("putmap={}", JSONUtil.toJsonStr(map));
Thread.sleep(2000);
log.info("过期前更新update map={}", JSONUtil.toJsonStr(map));
}
执行结果:
10:59:52.191 [main] INFO util.ExpiringMapTest - map={"testkey":"testValue2"}
10:59:56.201 [main] INFO util.ExpiringMapTest - putmap={"testkey":"testValue3"}
10:59:58.205 [main] INFO util.ExpiringMapTest - 过期前更新update map={"testkey":"testValue3"}
过期策略为ExpirationPolicy.ACCESSED
@Test
public void testACCESSED() throws InterruptedException {
ExpiringMap<String, String> map = ExpiringMap.builder().expiration(3000, TimeUnit.MILLISECONDS).
expirationPolicy(ExpirationPolicy.ACCESSED)
.build();
map.put("testkey", "testValue");
log.info("map={}", JSONUtil.toJsonStr(map));
Thread.sleep(2000);
log.info("get map key={}", map.get("testkey"));
Thread.sleep(2000);
log.info("sleep map={}", JSONUtil.toJsonStr(map));
}
执行结果:
11:04:06.510 [main] INFO util.ExpiringMapTest - map={"testkey":"testValue"}
11:04:08.519 [main] INFO util.ExpiringMapTest - sleep map=testValue
11:04:10.522 [main] INFO util.ExpiringMapTest - sleep map={"testkey":"testValue"}
设置最大maxSize,超出再次插入会从第一个值过期
@Test
public void testMaxSize() throws InterruptedException {
ExpiringMap<String, String> map = ExpiringMap.builder().maxSize(10)
.build();
for (int i = 0; i < 10; i++) {
map.put("key" + i, "value" + i);
}
log.info("key0={}", map.get("key0"));
map.put("key100", "value100");
log.info("key0={}", map.get("key0"));
log.info("key1={}", map.get("key1"));
}
执行结果:
11:08:07.173 [main] INFO util.ExpiringMapTest - key0=value0
11:08:07.179 [main] INFO util.ExpiringMapTest - key0=null
11:08:07.179 [main] INFO util.ExpiringMapTest - key1=value1
过期key监听,可实现多个监听
@Test
public void testExpirationListener() throws InterruptedException {
ExpiringMap<String, String> map = ExpiringMap.builder().
expiration(3000, TimeUnit.MILLISECONDS).
expirationListener((key, value) -> {
log.info("过期监听1,key={},value={}", key, value);
}).expirationListener((key, value) -> {
log.info("过期监听2,key={},value={}", key, value);
}).build();
map.put("testkey", "testValue");
log.info("map={}", JSONUtil.toJsonStr(map));
Thread.sleep(3000);
log.info("sleep map={}", JSONUtil.toJsonStr(map));
}
执行结果:
11:17:01.517 [main] INFO util.ExpiringMapTest - map={"testkey":"testValue"}
11:17:04.447 [ExpiringMap-Expirer] INFO util.ExpiringMapTest - 过期监听1,key=testkey,value=testValue
11:17:04.447 [ExpiringMap-Expirer] INFO util.ExpiringMapTest - 过期监听2,key=testkey,value=testValue
11:17:04.525 [main] INFO util.ExpiringMapTest - sleep map={}
引入pom
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.8</version>
</dependency>
参考
expiringmap github