zoukankan      html  css  js  c++  java
  • HashMap+线程池+优先队列实现带过期时间的LRUCache

    LRU算法

    Least Recently Used 意思是最近最少使用,是一种常用的置换算法,当你向一个队列或者其他容器中添加任务或者页面时容器已满,该算法会自动清理一个位置给你,今天我实现的就是添加了过期时间同时能够自动清理过期时间的LRU算法

    下面是实现和思路

    package interview;
    
    
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @ Author     :fqg
     * @ Date       :Created in 12:12 2020/8/25
     */
    public class TimeOutLRU {
        static class Node implements Comparable<Node>{
            String key;
            Object value;
            Long expireTime;
            public Node(){}
            public Node(String key, Object value, long expireTime){
                this.key = key;
                this.value = value;
                this.expireTime = expireTime;
            }
            //内比较器的重写
            @Override
            public int compareTo(Node o) {
                long l = this.expireTime - o.expireTime;
                if(l < 0) return -1;
                if(l > 0) return 1;
                return 0;
            }
        }
        //线程池中的worker线程
        static class ExpireThread implements Runnable{
    
            @Override
            public void run() {
                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 ConcurrentHashMap<String, Node> map;
        //使用优先队列,在队列内将Node进行排序
        private static volatile PriorityQueue<Node> queue;
        //线程池,这里使用定时任务线程池
        private static ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(10);
        //双从检查锁
        private PriorityQueue<Node> getInstance(){
            if(queue == null){
                synchronized(TimeOutLRU.class){
                    if(queue == null){
                        queue = new PriorityQueue<>(1024);
                    }
                }
            }
            return queue;
        }
        //constructor
        public TimeOutLRU(){
            map = new ConcurrentHashMap<>();
            queue = getInstance();
            //每隔三秒获取queue的头结点,查看是否过期。
            pool.scheduleWithFixedDelay(new ExpireThread(), 0, 3, TimeUnit.SECONDS);
        }
        //expose method
        public Object set(String key, Object value, long time){
            //获取过期时间
            long timeout = System.currentTimeMillis() + time;
            Node newNode = new Node(key, value, timeout);
            Node old = map.put(key, newNode);
            queue.offer(newNode);
            if(old != null){
                queue.remove(old);
                return old.value;
            }
            return null;
        }
    
        public Object get(String key){
            Node n = map.get(key);
            return n == null ? null : n.value;
        }
    
        public static void main(String[] args) throws InterruptedException {
            TimeOutLRU timeOutLRU = new TimeOutLRU();
            timeOutLRU.set("1","fqg",1000);
            Thread.sleep(1000);
            Object str = timeOutLRU.get("1");
            System.out.println(str);
        }
    }

     测试结果如下

    问题:

    1.实现思路总结

    重新定义个一个Node添加过期时间字段,使用优先队列和ConcurrentHashaMap来存值和过期检测,使用定时任务线程池来循环检测优先队列的头结点是否过期,如果过期就删除(实现过程中没有实现队列满了,或者其他特殊情况,当时我想的是如果队列满了,直接删除头结点就行,因为毕竟是个优先级队列,头结点的过期时间永远是最近的)

    2.Comparator和Comparable两个比较器的区别

    一个在内部使用一个在外部使用,用处不同意义相同但是体现的思想不同,内比较器体现的封装,外比较器体现的扩展。

  • 相关阅读:
    苹果IPhone真机开发调试
    Unity3d 错误提示 GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced
    Unity编辑器环境在Inspector面板中显示变量
    微信小程序开发
    Android 9.0 Http不能访问网络
    c#传不确定的参数个数,比如int型
    玩转@Git三剑客
    白话法律42讲-为程序员打造的专属法律武器
    uSurvival 1.41多人在线生存逃杀吃鸡类游戏源码
    NGUI: Next-Gen UI 2018.3.0f
  • 原文地址:https://www.cnblogs.com/frank9571/p/13559544.html
Copyright © 2011-2022 走看看