zoukankan      html  css  js  c++  java
  • LRUCache , LFUCach 实现源码 案例

    1.缓存工具类  LRUCache<K, V>

    package com.linyang.cache;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 本地缓存工具类
     * LRU
     */
    public class LRUCache<K, V> {
    
        private class Node{
            Node prev;
            Node next;
            Object key;
            Object value;
    
            public Node(Object key, Object value) {
                this.key = key;
                this.value = value;
                this.prev = null;
                this.next = null;
            }
        }
    
    
        private int capacity;
    
        private ConcurrentHashMap<Object, Node> concurrentHashMap;
    
        private Node head = new Node(-1, -1);
        private Node tail = new Node(-1, -1);
    
        public LRUCache(int capacity) {
            // write your code here
            this.capacity = capacity;
            this.concurrentHashMap = new ConcurrentHashMap<>(capacity);
            tail.prev = head;
            head.next = tail;
        }
    
        /**
         * 获取缓存
         *
         * @param key
         * @return
         */
        public Object get(K key) {
            checkNotNull(key);
            if (concurrentHashMap.isEmpty()) return null;
            if (!concurrentHashMap.containsKey(key)) return null;
            Node current = concurrentHashMap.get(key);
            // 将当前链表移出
            current.prev.next = current.next;
            current.next.prev = current.prev;
    
            move_to_tail(current);
    
            return current.value;
        }
    
        /**
         * 添加缓存
         *
         * @param key
         * @param value
         */
        public void put(K key, V value) {
            checkNotNull(key);
            checkNotNull(value);
            // 当缓存存在时,更新缓存
            if (concurrentHashMap.containsKey(key)){
                Node current = concurrentHashMap.get(key);
                // 将当前链表移出
                current.prev.next = current.next;
                current.next.prev = current.prev;
    
                move_to_tail(current);
                return;
            }
            // 已经达到最大缓存
            if (isFull()) {
                concurrentHashMap.remove(head.next.key);
                head.next.next.prev = head;
                head.next = head.next.next;
            }
            Node node = new Node(key,value);
            concurrentHashMap.put(key,node);
            move_to_tail(node);
        }
    
        /**
         * 检测字段是否合法
         *
         * @param reference
         * @param <T>
         * @return
         */
        public static <T> T checkNotNull(T reference) {
            if (reference == null) {
                throw new NullPointerException();
            }
            return reference;
        }
    
        /**
         * 判断是否达到最大缓存
         *
         * @return
         */
        private boolean isFull() {
            return concurrentHashMap.size() == capacity;
        }
    
        private void move_to_tail(Node current) {
            // 将当前链表添加到尾部
            tail.prev.next = current;
            current.prev = tail.prev;
            tail.prev = current;
            current.next = tail;
        }
    
    }
    

      

    2.缓存工具类  LFUCache<K, V>

    package com.linyang.cache;
    
    import java.util.Collections;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 本地缓存工具类
     */
    public class LFUCache<K, V> {
    
        private ConcurrentHashMap<Object, Cache> concurrentHashMap;
    
        final int size;
    
    
        public LFUCache(int capacity) {
            this.size = capacity;
            this.concurrentHashMap = new ConcurrentHashMap<>(capacity);
            new Thread(new TimeoutTimerThread()).start();
        }
    
        /**
         * 获取缓存
         *
         * @param key
         * @return
         */
        public Object get(K key) {
            checkNotNull(key);
            if (concurrentHashMap.isEmpty()) return null;
            if (!concurrentHashMap.containsKey(key)) return null;
            Cache cache = concurrentHashMap.get(key);
            if (cache == null) return null;
            cache.setHitCount(cache.getHitCount()+1);
            cache.setAccessTime(System.currentTimeMillis());
            return cache.getValue();
        }
    
        /**
         * 添加缓存
         *
         * @param key
         * @param value
         */
        public void put(K key, V value,long expire) {
            checkNotNull(key);
            checkNotNull(value);
            // 当缓存存在时,更新缓存
            if (concurrentHashMap.containsKey(key)){
                Cache cache = concurrentHashMap.get(key);
                cache.setHitCount(cache.getHitCount()+1);
                cache.setWriteTime(System.currentTimeMillis());
                cache.setAccessTime(System.currentTimeMillis());
                cache.setExpireTime(expire);
                cache.setValue(value);
                return;
            }
            // 已经达到最大缓存
            if (isFull()) {
                Object kickedKey = getKickedKey();
                if (kickedKey !=null){
                    // 移除最少使用的缓存
                    concurrentHashMap.remove(kickedKey);
                }else {
                    return;
                }
            }
            Cache cache = new Cache();
            cache.setKey(key);
            cache.setValue(value);
            cache.setWriteTime(System.currentTimeMillis());
            cache.setAccessTime(System.currentTimeMillis());
            cache.setHitCount(1);
            cache.setExpireTime(expire);
            concurrentHashMap.put(key, cache);
        }
    
        /**
         * 检测字段是否合法
         *
         * @param reference
         * @param <T>
         * @return
         */
        public static <T> T checkNotNull(T reference) {
            if (reference == null) {
                throw new NullPointerException();
            }
            return reference;
        }
    
        /**
         * 判断是否达到最大缓存
         *
         * @return
         */
        private boolean isFull() {
            return concurrentHashMap.size() == size;
        }
    
        /**
         * 获取最少使用的缓存
         * @return
         */
        private Object getKickedKey() {
            Cache min = Collections.min(concurrentHashMap.values());
            return min.getKey();
        }
    
    
    
    
        /**
         * 处理过期缓存
         */
        class TimeoutTimerThread implements Runnable {
            public void run() {
                while (true) {
                    try {
                        TimeUnit.SECONDS.sleep(60);
                        expireCache();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
    
            /**
             * 创建多久后,缓存失效
             *
             * @throws Exception
             */
            private void expireCache() throws Exception {
                System.out.println("检测缓存是否过期缓存");
                for (Object key : concurrentHashMap.keySet()) {
                    Cache cache = concurrentHashMap.get(key);
                    long timoutTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()
                            - cache.getWriteTime());
                    if (cache.getExpireTime() > timoutTime) {
                        continue;
                    }
                    System.out.println(" 清除过期缓存 : " + key);
                    //清除过期缓存
                    concurrentHashMap.remove(key);
                }
            }
        }
    
    }
    

      

    main方法

    package com.linyang.cache;
    
    /**
     * localcache
     * 
     * @author YinTao
     * 2020-03-24
     */
    public class app {
        public static void main(String[] args) throws Exception {
    ////        LFUCache localCache = new LFUCache();
    ////        localCache.put("key", "66666");
    ////        System.out.println(localCache.get("key"));
    ////        TimeUnit.SECONDS.sleep(6);
    ////        System.out.println("清除缓存后:"+localCache.get("key"));
    //
    //        FileWriter writer = new FileWriter("txt.txt");
    //        BufferedWriter bufferedWriter = new BufferedWriter(writer);
    ////        for(int i = 0;i<5;i++){
    ////            bufferedWriter.write("");
    //        bufferedWriter.write("哈哈哈哈哈
    哈哈哈哈哈
    哈哈哈哈哈
    哈哈哈哈哈
    哈哈哈哈哈
    ");
    //        bufferedWriter.newLine();
    //        bufferedWriter.flush();
    //
    //
    ////        }
    //        LFUCache localCache = new LFUCache(3);
    //        for (int i = 0; i < 3; i++) {
    //            localCache.put("01"+i, "张三"+i,2*60);
    //        }
    //        localCache.get("010");
    //        localCache.get("011");
    //        localCache.get("010");
    //        localCache.put("013","李四",2*60);
    //
    //        for (int i = 0; i < 4; i++) {
    //            System.out.println(localCache.get("01"+i));
    //        }
    
            LRUCache lruCache = new LRUCache(6);
    //        for (int i = 0; i < 5; i++) {
    //            lruCache.put("lru"+i, "张三"+i);
    //        }
            lruCache.put(123, "{0x00, 0x10, 0x02, 0x00}");
            lruCache.put("lru5","李四");
    
    //        for (int i = 0; i < 6; i++) {
    //            System.out.println(lruCache.get("lru"+i));
    //        }
            System.out.println(lruCache.get("lru5"));
            System.out.println(lruCache.get(123));
        }
    }
    
  • 相关阅读:
    几何——BAPC2019 K
    dsu on tree —— BAPC2019 A
    概率dp——BAPC2019 L
    计算几何+三分求极值——cf1046I
    上下文管理器
    转 -- 一行式
    转--python 基础
    转--python 面试题
    转 -- Python: 多继承模式下 MRO(Method Resolution Order) 的计算方式关乎super
    转--python之正则入门
  • 原文地址:https://www.cnblogs.com/adao21/p/12560711.html
Copyright © 2011-2022 走看看