• 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));
        }
    }
    
  • 相关阅读:
    hdu 5646 DZY Loves Partition
    bzoj 1001 狼抓兔子 平面图最小割
    poj 1815 Friendship 最小割 拆点 输出字典序
    spoj 1693 Coconuts 最小割 二者取其一式
    hdu 5643 King's Game 约瑟夫环变形
    约瑟夫环问题
    hdu 5642 King's Order
    CodeForces 631C Report
    1039: C语言程序设计教程(第三版)课后习题9.4
    1043: C语言程序设计教程(第三版)课后习题10.1
  • 原文地址:https://www.cnblogs.com/adao21/p/12560711.html
Copyright © 2020-2023  润新知