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));
        }
    }
    
  • 相关阅读:
    POJ 1703 Find them, Catch them
    POJ 2236 Wireless Network
    POJ 2010 Moo University
    POJ 2184 Cow Exhibition
    POJ 3280 Cheapest Palindrome
    POJ 3009 Curling 2.0
    POJ 3669 Meteor Shower
    POJ 2718 Smallest Difference
    POJ 3187 Backward Digit Sums
    POJ 3050 Hopscotch
  • 原文地址:https://www.cnblogs.com/adao21/p/12560711.html
Copyright © 2011-2022 走看看