欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA利用优先队列PriorityQueue+ConcurrentHashMap实现带过期时间的LRU

程序员文章站 2022-07-03 11:13:41
思路:每次添加新结点时,判断Map中是否已有,如果有,移动到队头;没有的话就新建一个结点放入。对于带过期时间的功能,使用PriorityQueue将过期时间最小的Node放在队首,到时间删除结点。package LRU;public class Node implements Comparable{ private String key; private Object value; private long expireTime;//过期时间...

不带过期时间的(链表+Map实现):https://blog.csdn.net/weixin_42970433/article/details/107896933

思路:
每次添加新结点时,判断Map中是否已有,如果有,移动到队头;没有的话就新建一个结点放入。
对于带过期时间的功能,使用PriorityQueue将过期时间最小的Node放在队首,到时间删除结点。

package LRU; public class Node implements Comparable<Node>{ private String key; private Object value; private long expireTime;//过期时间 public Node(String key, Object value, long expireTime) { this.key = key; this.value = value; this.expireTime = expireTime; } //按照过期时间排序 升序 @Override public int compareTo(Node o) { long r=this.expireTime-o.expireTime; if(r>0) return 1; if(r<0) return -1; return 0; } public long getExpireTime() { return expireTime; } public String getKey() { return key; } public Object getValue() { return value; } } 
package LRU; import java.util.PriorityQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class LRU { //用于设置清除过期数据的线程池 private static ScheduledExecutorService swapExpiredPool =new ScheduledThreadPoolExecutor(10); //用户存储数据,为了保证线程安全,使用ConcurrentHashMap private ConcurrentHashMap<String,Node> cache=new ConcurrentHashMap<>(1024); //保存最新的过期数据,过期时间最小的数据排在队列前 private PriorityQueue<Node> expireQueue=new PriorityQueue<>(1024); //构造方法:只要有缓存了,过期清除线程就开始工作 public LRU(){ swapExpiredPool.scheduleWithFixedDelay(new ExpiredNode(),3,3, TimeUnit.SECONDS); } class ExpiredNode implements Runnable{ @Override public void run(){ //获取当前时间 long now=System.currentTimeMillis(); //从过期队列弹出队首元素,如果不存在,或者不过期就返回 while(true){ Node node=expireQueue.peek();//获得队首 if(node==null||node.getExpireTime()>now){ return; } cache.remove(node.getKey()); expireQueue.poll();//弹出队首 } } } public Object set(String key,Object value,long ttl){ //获取过期时间点 long expireTime=System.currentTimeMillis()+ttl; //新建一个结点 Node newNode=new Node(key,value,expireTime); //cache中有的话就覆盖,没有就添加新的,过期时间队列也要添加 Node old=cache.put(key,newNode); expireQueue.add(newNode); //如果该key存在数据,还要从过期时间队列删除 if(old!=null){ expireQueue.remove(old); return old.getValue(); } return null; } public Object get(String key){ //从cache直接获取 Node n=cache.get(key); if(n==null) return null; else return n.getValue(); } } 

本文地址:https://blog.csdn.net/weixin_42970433/article/details/107896626

相关标签: 队列 java LRU