这个是我使用 Java 内置的 MAP 实现的简易缓存,适用于一些轻量级缓存,现在公开出来,希望能帮助到大家:
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.util.Pair;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* 使用 Java 内置的 MAP 实现的简易缓存,适用于一些轻量级缓存
*
* @author hengyumo
* @since 2021-06-06
*/
@Slf4j
public class DawnSimpleCache {
/**
* 保存缓存数据
*/
private final Map<String, Object> cache;
/**
* 保存缓存对应的过期时间
*/
private final Map<String, Long> cacheExpireRecord;
public DawnSimpleCache() {
cache = new ConcurrentHashMap<>();
cacheExpireRecord = new ConcurrentHashMap<>();
}
public Pair<Boolean, Optional<?>> getFromCache(String key) {
boolean cacheContainsKey = true;
Object value = null;
Long expireTime = cacheExpireRecord.get(key);
// 如果存在这个Key
if (expireTime != null) {
// 如果数据已经过期,此处使用了延迟删除,只有查询发现过期了才会删除
// 0L是特殊的,它代表永不过期
if (expireTime != 0L && expireTime < System.currentTimeMillis()) {
log.info("SIMPLE CACHE缓存过期:" + key);
deleteCache(key);
cacheContainsKey = false;
} else {
// 从缓存中获取数据
value = cache.get(key);
}
} else {
cacheContainsKey = false;
}
return Pair.of(cacheContainsKey, Optional.ofNullable(value));
}
public int deleteCache(String keyPrefix) {
Set<String> keys = new HashSet<>();
// 先查到以这个前缀开头的所有Key
cache.forEach((k, v) -> {
if (k.startsWith(keyPrefix)) {
keys.add(k);
}
});
// 遍历这些Key,依次清除
keys.forEach(key -> {
cacheExpireRecord.remove(key);
cache.remove(key);
log.info("SIMPLE CACHE缓存清除:" + key);
});
return keys.size();
}
public void setCache(String key, Object value, long timeToLive, TimeUnit timeUnit) {
cache.put(key, value);
// 记录失效时间
if (timeToLive <= 0L) {
cacheExpireRecord.put(key, 0L);
} else {
cacheExpireRecord.put(key, System.currentTimeMillis() + timeUnit.toMillis(timeToLive));
}
}
}
其中cacheExpireRecord这个Map的用途就是用来保存缓存的过期时间,代码中使用了延迟删除,只有查询发现过期了才会删除
,0L是特殊的,它代表永不过期。
这个SimpleCache代码简单,功能也简单,但对于一些简单轻量的缓存,却也足够使用了。