带过期时间的本地缓存

带过期时间的本地缓存

实现原理

利用定时任务实现缓存的过期检查,每次任务扫描队列中的任务,检查是否过期,过期则删除。

使用场景

  1. 缓存指定时间内过期 ,适合在缓存自动管理;
  2. 缓存过期时触发事件 ,适合用于监控过期事件;

代码

`@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;
}

}`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值