1、功能简介
- 可设置Map中的Entry在一段时间后自动过期。
- 可设置Map最大容纳值,当到达Maximum size后,再次插入值会导致Map中的第一个值过期。
- 可添加监听事件,在监听到Entry过期时调度监听函数。
- 可以设置懒加载,在调用get()方法时创建对象。
2、依赖
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.10</version>
</dependency>
3、详细使用介绍
import net.jodah.expiringmap.ExpirationListener;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author JHL
* @version 1.0
* @date 2023/6/15 14:08
* @since : JDK 11
*/
public class T {
public static void main(String[] args) {
// test1();
// test2();
// test3();
// test4();
// test5();
// test6();
// test7();
// test8();
while (true) {
}
}
/**
* 创建key就开始对key存在的时长计时,过期则去除这个key
* 过期策略:ExpirationPolicy.CREATED
*/
private static void test1() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.expiration(5000, TimeUnit.MILLISECONDS)
.expirationPolicy(ExpirationPolicy.CREATED)
.build();
map.put("key", "value");
try {
System.out.println(map.get("key")); // value
Thread.sleep(2000);
System.out.println("######################### \t[ 经过2秒 ]\t #########################");
System.out.println(map.get("key")); // value
System.out.println("######################### \t[ 经过5秒 ]\t #########################");
Thread.sleep(3000);
System.out.println(map.get("key")); // 此时已过期 null
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 对指定key的value进行更新后将对此key重新计时
* put()、replace()为更新key的操作
* 过期策略:ExpirationPolicy.CREATED
*/
private static void test2() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.expiration(5000, TimeUnit.MILLISECONDS)
.expirationPolicy(ExpirationPolicy.CREATED)
.build();
map.put("key1", "value1");
map.put("key2", "value2");
try {
System.out.println(map.get("key1")); // value1
System.out.println(map.get("key2")); // value2
Thread.sleep(4000);
System.out.println("######################### \t[ 经过4秒,并且更新key1 ]\t #########################");
// map.put("key1", "123");
map.replace("key1", "123");
System.out.println(map.get("key1")); // 123
System.out.println(map.get("key2")); // value2
Thread.sleep(1000);
System.out.println("######################### \t[ 经过5秒 ]\t #########################");
System.out.println(map.get("key1")); // 123
System.out.println(map.get("key2")); // null
Thread.sleep(3500);
System.out.println("######################### \t[ 经过9.5秒 ]\t #########################");
System.out.println(map.get("key1")); // 123
System.out.println(map.get("key2")); // null
Thread.sleep(500);
System.out.println("######################### \t[ 经过10秒 ]\t #########################");
System.out.println(map.get("key1")); // null
System.out.println(map.get("key2")); // null
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 在每次访问指定key,则该key的过期时间会重置。
* 过期策略:ExpirationPolicy.ACCESSED
*/
private static void test3() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.expiration(5000, TimeUnit.MILLISECONDS)
.expirationPolicy(ExpirationPolicy.ACCESSED)
.build();
map.put("key", "value");
try {
System.out.println(map.get("key")); // value
Thread.sleep(4000);
System.out.println("######################### \t[ 经过4秒 ]\t #########################");
System.out.println(map.get("key")); // value
Thread.sleep(4000);
System.out.println("######################### \t[ 经过8秒 ]\t #########################");
System.out.println(map.get("key")); // value
Thread.sleep(4000);
System.out.println("######################### \t[ 经过12秒 ]\t #########################");
System.out.println(map.get("key")); // value
Thread.sleep(5001);
System.out.println("######################### \t[ 经过17秒 ]\t #########################");
System.out.println(map.get("key")); // null
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* 添加新key时指定过期时长与过期策略
*/
private static void test4() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.variableExpiration()
.expirationPolicy(ExpirationPolicy.CREATED)
.build();
map.put("key1", "value1", ExpirationPolicy.ACCESSED, 5000, TimeUnit.MILLISECONDS);
map.put("key2", "value2", 10000, TimeUnit.MILLISECONDS);
try {
Thread.sleep(2000);
System.out.println("######################### \t[ 2秒后 ]\t #########################");
System.out.println(map.get("key1")); // value1
System.out.println(map.get("key2")); // value2
Thread.sleep(4999);
// Thread.sleep(5001);
System.out.println("######################### \t[ 7秒后 ]\t #########################");
System.out.println(map.get("key1")); // null
System.out.println(map.get("key2")); // value2
Thread.sleep(3000);
System.out.println("######################### \t[ 10秒后 ]\t #########################");
System.out.println(map.get("key1")); // null
System.out.println("key2:" + map.get("key2")); // null
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 超map的最大容量时,移除最老的key
*/
private static void test5() {
// 设置最大容量为10;
ExpiringMap<String, String> map = ExpiringMap
.builder()
.maxSize(10)
.build();
int size = 10;
System.out.println("######################### \t[ 添加10个key ]\t #########################");
for (int i = 0; i < size; i++) {
map.put("key" + i, "value" + i);
}
System.out.println("######################### \t[ 打印10个key的值 ]\t #########################");
for (int i = 0; i < size; i++) {
System.out.println(map.get("key" + i));
}
System.out.println("######################### \t[ 在加10个AAA ]\t #########################");
for (int i = 0; i < size; i++) {
map.put("AAA" + i, "a" + i);
}
System.out.println("######################### \t[ 打印10个key ]\t #########################");
for (int i = 0; i < 10; i++) {
System.out.println(map.get("key" + i));
}
System.out.println("######################### \t[ 打印10个AAA ]\t #########################");
for (int i = 0; i < 10; i++) {
System.out.println(map.get("AAA" + i));
}
}
/**
* 过期回调,指定存活时长的key在经过限制时长后过期,回调某个方法
* 不指定过期策略时,默认使用:ExpirationPolicy.CREATED
*/
private static void test6() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.variableExpiration()
.expirationListener((k, v) -> System.out.println("过期了:" + k))
.build();
map.put("key", "value", 5000, TimeUnit.MILLISECONDS);
try {
Thread.sleep(2000);
System.out.println(map.get("key")); // value
Thread.sleep(2800);
System.out.println(map.get("key")); // value
Thread.sleep(200);
System.out.println(map.get("key")); // null
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 在运行时动态 添加/删除 过期事件监听器
*/
private static void test7() {
ExpiringMap<String, String> map = ExpiringMap
.builder()
.variableExpiration()
.build();
ExpirationListener<String, String> expirationListener = ((key, value) -> System.out.println("过期事件" + "key:" + key + " value:" + value));
try {
// 1、先添加key
map.put("key", "value", ExpirationPolicy.CREATED, 5000, TimeUnit.MILLISECONDS);
// 2、在添加监听
Thread.sleep(1000);
System.out.println("######################### \t[ 1秒后 ]\t #########################");
map.addExpirationListener(expirationListener);
// 3、等待key过期
System.out.println("######################### \t[ 5秒后 ]\t #########################");
Thread.sleep(4001);
// 4、清除监听
map.removeExpirationListener(expirationListener);
map.put("key2", "value2", ExpirationPolicy.CREATED, 2000, TimeUnit.MILLISECONDS);
Thread.sleep(2001);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用懒加载模式,不用主动向map中put对象,在调用get方法时自动去创建对象。
*/
private static void test8() {
Map<String, Connection> map = ExpiringMap
.builder().expiration(5000, TimeUnit.MILLISECONDS)
.expirationListener((key, value) -> System.out.println("过期:" + key))
.entryLoader(ip -> new Connection((String) ip))
.build();
try {
System.out.println(map.get("127.0.0.1"));
System.out.println(map.get("127.0.0.2"));
System.out.println(map.get("127.0.0.3"));
System.out.println(map.get("127.0.0.4"));
Thread.sleep(5010);
System.out.println("######################### \t[ 执行结束 ]\t #########################");
} catch (Exception e) {
e.printStackTrace();
}
}
static class Connection {
String ip;
public Connection(String ip) {
this.ip = ip;
}
@Override
public String toString() {
return "Connection{" + "ip='" + ip + '\'' + '}';
}
}
}