实现原理
利用定时任务实现缓存的过期检查,每次任务扫描队列中的任务,检查是否过期,过期则删除。
使用场景
- 缓存指定时间内过期 ,适合在缓存自动管理;
- 缓存过期时触发事件 ,适合用于监控过期事件;
代码
`@Service
@Slf4j
public class LocalCache {
private static final int MAX_CAPACITY = 100000;
private static final int DEFAULT_CAPACITY = 1024;
private Map<String, CacheEntity> cache = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
@Autowired
private EventService eventService;
public LocalCache() {
executor.scheduleWithFixedDelay(new TaskThread(), 0, 1, TimeUnit.MINUTES);
}
public <T> boolean set(String key, T value, long expire) {
return set(key, value, System.currentTimeMillis(), expire);
}
public <T> boolean set(String key, T value, long saveTime, long expire) {
if (key == null || value == null) {
return false;
}
if (cache.size() > MAX_CAPACITY) {
log.error("[map space is full]");
return false;
}
CacheEntity<T> cacheEntity = new CacheEntity<>(key, value, saveTime, expire);
cache.put(key, cacheEntity);
log.info("[设置上传文件缓存]key:{},value:{}", key, cacheEntity);
return true;
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
CacheEntity cacheEntity = cache.remove(key);
if (cacheEntity == null) {
return null;
}
return (T) cacheEntity.getValue();
}
@SuppressWarnings("unchecked")
public <T> T remove(String key) {
if (!cache.containsKey(key)) {
return null;
}
CacheEntity cacheEntity = cache.remove(key);
if (cacheEntity != null) {
return (T) cacheEntity.getValue();
}
return null;
}
public boolean containsKey(String key) {
return cache.containsKey(key);
}
private class TaskThread implements Runnable {
@Override
public void run() {
try {
CacheEntity cacheEntity;
Iterator<Map.Entry<String, CacheEntity>> iterator = cache.entrySet().iterator();
String key;
while (iterator.hasNext()) {
Map.Entry<String, CacheEntity> entry = iterator.next();
key = entry.getKey();
cacheEntity = entry.getValue();
long currentTime = System.currentTimeMillis();
if (cacheEntity.getSaveTime() + cacheEntity.getExpire() < currentTime) {
log.info("[key过期][key:{}, cacheEntity:{}, expireTime:{}, currentTime:{}]", key, JSON.toJSONString(cacheEntity),
cacheEntity.getSaveTime() + cacheEntity.getExpire(), currentTime);
iterator.remove();
}
}
} catch (Exception e) {
log.warn("定时任务异常:", e);
}
}
}
}`
`@Data
@AllArgsConstructor
@NoArgsConstructor
public class CacheEntity implements Comparable<CacheEntity> {
private String key;
private T value;
/**
* 保存文件缓存时间戳
/
private long saveTime;
/*
* 有效时长
*/
private long expire;
@Override
public int compareTo(@NotNull CacheEntity<T> cacheEntity) {
long thisTime = this.saveTime + this.expire;
long otherTime = cacheEntity.getSaveTime() + cacheEntity.getExpire();
long diff = thisTime - otherTime;
if (diff > 0) {
return 1;
}
if (diff < 0) {
return -1;
}
return 0;
}
}`