package com.shinedata.cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @ClassName LocalCache
* @Author yupanpan
* @Date 2021/3/2 15:29
*/
public class LocalCache {
private static Logger logger = LoggerFactory.getLogger(LocalCache.class);
private static final int MAX_CAPACITY = 100000;
private static final int DEFAULT_CAPACITY = 1024;
private static Map<String, CacheEntity> cache = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
static {
executor.scheduleWithFixedDelay(new TaskThread(), 0, 1, TimeUnit.SECONDS);
}
/**
* 带过期时间的key-value
* @param key
* @param object
* @param cacheTime
* @return
*/
public static boolean set(String key, Object object,long cacheTime) {
if (key == null || object == null) {
return false;
}
if (cache.size() > MAX_CAPACITY) {
logger.error("[map space is full]");
return false;
}
CacheEntity cacheEntity = new CacheEntity(key, object, System.currentTimeMillis()/1000, cacheTime, true);
cache.put(key, cacheEntity);
return true;
}
/**
* 不带过期时间的key-value
* @param key
* @param object
* @return
*/
public static boolean set(String key, Object object) {
if (key == null || object == null) {
return false;
}
if (cache.size() > MAX_CAPACITY) {
logger.error("[map space is full]");
return false;
}
CacheEntity cacheEntity = new CacheEntity(key, object, System.currentTimeMillis()/1000, -1, false);
cache.put(key, cacheEntity);
return true;
}
public static Object get(String key) {
CacheEntity cacheEntity = cache.get(key);
if (cacheEntity == null) {
return null;
}
return cacheEntity.getValue();
}
public Object remove(String key) {
if (!cache.containsKey(key)) {
return null;
}
CacheEntity cacheEntity = cache.remove(key);
if (cacheEntity != null) {
return cacheEntity.getValue();
}
return null;
}
public boolean containsKey(String key) {
return cache.containsKey(key);
}
private static 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() / 1000;
if (cacheEntity.getIsExpire() != null
&& cacheEntity.getIsExpire()
&& cacheEntity.getCreateTime() + cacheEntity.getCacheTime() <= currentTime) {
// logger.info("[key过期][key:{}, cacheEntity:{}]", key, JSON.toJSONString(cacheEntity));
iterator.remove();
//可以做key过期事件处理
}
}
} catch (Exception e) {
logger.warn("定时任务异常:", e);
}
}
}
}
实体类
package org.linlinjava.litemall.wx.cache;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName CacheEntity
* @Date 2021/3/2 15:30
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CacheEntity {
private String key;
private Object value;
//创建时间-当前秒
private long createTime;
/*
* 缓存时间-秒
*/
private long cacheTime;
//是否需要过期
private Boolean isExpire=false;
}
思路是每秒轮训一遍到过期时间的key删除