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("哈哈哈哈哈\n哈哈哈哈哈\n哈哈哈哈哈\n哈哈哈哈哈\n哈哈哈哈哈\n"); // 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)); } }