packageinterview;import java.util.*;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.ScheduledThreadPoolExecutor;importjava.util.concurrent.TimeUnit;/*** @ Author :fqg
* @ Date :Created in 12:12 2020/8/25*/
public classTimeOutLRU {static class Node implements Comparable{
String key;
Object value;
Long expireTime;publicNode(){}public Node(String key, Object value, longexpireTime){this.key =key;this.value =value;this.expireTime =expireTime;
}//内比较器的重写
@Overridepublic intcompareTo(Node o) {long l = this.expireTime -o.expireTime;if(l < 0) return -1;if(l > 0) return 1;return 0;
}
}//线程池中的worker线程
static class ExpireThread implementsRunnable{
@Overridepublic voidrun() {long now =System.currentTimeMillis();while (true) {
Node n=queue.peek();if(n == null || n.expireTime > now) return;
queue.remove(n);
map.remove(n.key);
System.out.println("清除成功");
}
}
}//内部容量,保证线程安全使用concurrentHashMap同时将queue设置成单例模式
private static ConcurrentHashMapmap;//使用优先队列,在队列内将Node进行排序
private static volatile PriorityQueuequeue;//线程池,这里使用定时任务线程池
private static ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(10);//双从检查锁
private PriorityQueuegetInstance(){if(queue == null){synchronized(TimeOutLRU.class){if(queue == null){
queue= new PriorityQueue<>(1024);
}
}
}returnqueue;
}//constructor
publicTimeOutLRU(){
map= new ConcurrentHashMap<>();
queue=getInstance();//每隔三秒获取queue的头结点,查看是否过期。
pool.scheduleWithFixedDelay(new ExpireThread(), 0, 3, TimeUnit.SECONDS);
}//expose method
public Object set(String key, Object value, longtime){//获取过期时间
long timeout = System.currentTimeMillis() +time;
Node newNode= newNode(key, value, timeout);
Node old=map.put(key, newNode);
queue.offer(newNode);if(old != null){
queue.remove(old);returnold.value;
}return null;
}publicObject get(String key){
Node n=map.get(key);return n == null ? null: n.value;
}public static void main(String[] args) throwsInterruptedException {
TimeOutLRU timeOutLRU= newTimeOutLRU();
timeOutLRU.set("1","fqg",1000);
Thread.sleep(1000);
Object str= timeOutLRU.get("1");
System.out.println(str);
}
}