1.1 查询缓存时,如果当前时间大于key的过期时间,则不返回,并且对该key进行删除
1.2 定时任务随机删除key,策略为随机从有过期时间的key中,抽样进行删除。
总结:性能最好,但是会占用比较多的内存空间
增加LRU算法,淘汰掉不常用的key值
使用延迟队列,对key定时删除
存储key的类
/** * @author Miguel.hou * @version v1.0 * @date 2020-05-26 */ @Data @AllArgsConstructor public class CacheItem implements Delayed { private String key; private String value; private Long expireSec; private Long currentTime; public CacheItem(String key, String value, Long expireSec) { this.key = key; this.value = value; this.expireSec = expireSec; this.currentTime = System.currentTimeMillis(); } @Override public long getDelay(TimeUnit unit) { // 还剩多少时间过期 return expireSec - TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - currentTime); } @Override public int compareTo(Delayed o) { return Long.compare(getDelay(TimeUnit.SECONDS), o.getDelay(TimeUnit.SECONDS)); } }
MyCahce.java
/** * @author Miguel.hou * @version v1.0 * @date 2020-05-26 */ public class MyCache implements Runnable { private boolean stop = false; private Map<String, CacheItem> cacheMap = new ConcurrentHashMap<>(); private DelayQueue<CacheItem> expireDelayQueue = new DelayQueue<CacheItem>(); public MyCache() { new Thread(this).start(); } public synchronized void set(String key, String value, Long expireSec) { CacheItem cacheItem = cacheMap.get(key); if (cacheItem != null) { cacheMap.remove(key); expireDelayQueue.remove(cacheItem); } CacheItem newCacheItem = new CacheItem(key, value, expireSec); expireDelayQueue.add(newCacheItem); } @SneakyThrows @Override public void run() { while (!stop) { CacheItem cacheItem = expireDelayQueue.take(); cacheMap.remove(cacheItem.getKey()); System.out.println("============ remove cache:" + cacheItem.getKey()); } } public void shutDown() { stop = true; } public static void main(String[] args) { MyCache myCache = new MyCache(); myCache.set("miguel1", "123", 5L); myCache.set("miguel2", "123", 10L); myCache.set("miguel3", "123", 15L); try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } } }