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

浙公网安备 33010602011771号