啥也不说,直接上代码,欢迎指正。
package com.example.demo.cache;
/**
* @className: JdkCache
* @description: TODO 类描述
* @author: Yang.H
* @date: 2021/8/2014:26
**/
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.*;
/**
* 设计一个JDK缓存
*/
@Slf4j
public class JdkCache {
private static final long NO_EXPIRE_TIME = -1;
// Key,Value 容器
private static final Map<String, ValueHolder> LOCAL_CACHE = new ConcurrentHashMap<>();
private static class ValueHolder {
// 缓存值
private String value;
// 修改时间
private Date modifyTime;
// 过期时间
private long expireTime;
}
private static final ScheduledExecutorService exeService = new ScheduledThreadPoolExecutor(1, (r) -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.setName("JDK失效缓存清空守护线程");
return thread;
});
static {
// 类初始化时,创建一个线程,用于不断的去判断key是否过期,然后删除。
exeService.scheduleAtFixedRate(() -> {
for (Map.Entry<String, ValueHolder> entry : LOCAL_CACHE.entrySet()) {
if (isExpire(entry.getValue())) {
String value = removeKey(entry.getKey());
log.info("缓存已失效。键:{}, 缓存值:{}", entry.getKey(), value);
} else {
log.info("缓存未失效。键:{}", entry.getKey());
}
}
}, 0, 500, TimeUnit.MILLISECONDS);
}
private static boolean isExpire(ValueHolder holder) {
if (holder.expireTime <= 0) { //不失效
return false;
}
return new Date().getTime() > holder.modifyTime.getTime() + holder.expireTime;
}
/**
* 删除过期的key,并返回值。返回null表示不符合要求
*
* @param key
* @return
*/
private static String removeExpireKey(String key) {
ValueHolder holder = LOCAL_CACHE.get(key);
if (holder != null && isExpire(holder)) {
log.info("缓存已失效。键:{}", key);
return (holder = LOCAL_CACHE.remove(key)) != null ? holder.value : null;
}
return null;
}
/**
* 删除key
*
* @param key
* @return
*/
public static String removeKey(String key) {
ValueHolder holder;
return (holder = LOCAL_CACHE.remove(key)) != null ? holder.value : null;
}
/**
* 存储,KV,但是过期时间不刷新
* @param key
* @param value
* @param millSecond
* @return
*/
public static String put(String key, String value, long millSecond) {
removeExpireKey(key);
ValueHolder valueHolder = LOCAL_CACHE.get(key);
if (valueHolder != null){
valueHolder.value = value;
}else {
valueHolder = new ValueHolder();
valueHolder.value = value;
valueHolder.expireTime = millSecond;
valueHolder.modifyTime = new Date();
}
return (valueHolder = LOCAL_CACHE.put(key, valueHolder)) == null ? null : valueHolder.value;
}
/**
* 存储Key,value,并指定过期时间. 刷新过期时间
*
* @param key
* @param value
* @param millSecond
* @return
*/
public static String putAndUpdateExpireTime(String key, String value, long millSecond){
removeExpireKey(key);
ValueHolder valueHolder = new ValueHolder();
valueHolder.value = value;
valueHolder.modifyTime = new Date();
valueHolder.expireTime = millSecond;
ValueHolder oldHolder = LOCAL_CACHE.put(key, valueHolder);
return oldHolder != null ? oldHolder.value : null;
}
/**
* 添加不过期的key
*
* @param key
* @param value
* @return
*/
public static String put(String key, String value) {
return putAndUpdateExpireTime(key, value, NO_EXPIRE_TIME);
}
/**
* 删除key
*
* @param key
* @return
*/
public static String remove(String key) {
ValueHolder valueHolder;
return (valueHolder = LOCAL_CACHE.remove(key)) == null ? null : valueHolder.value;
}
/**
* 获取key
*
* @param key
* @return
*/
public static String get(String key) {
removeExpireKey(key);
ValueHolder valueHolder;
return (valueHolder = LOCAL_CACHE.get(key)) == null ? null : valueHolder.value;
}
/**
* 获取,如果不存在,则返回默认值
*
* @param key
* @param defaultValue
* @return
*/
public static String getOrDefault(String key, String defaultValue) {
removeExpireKey(key);
ValueHolder valueHolder;
return (valueHolder = LOCAL_CACHE.get(key)) == null ? defaultValue : valueHolder.value;
}
}