目录
LRU缓存实现1——LinkedHashMap
使用可重入锁实现线程安全
import java.util.Map;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LRU<K, V> extends LinkedHashMap<K, V>{
private final int maxCapacity;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
private final Lock lock = new ReentrantLock();
public LRU(int maxCapacity) {
super(maxCapacity, DEFAULT_LOAD_FACTOR);
this.maxCapacity = maxCapacity;
}
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
return size() > maxCapacity;
}
public boolean containsKey(Object key) {
try {
lock.lock();
return super.containsKey(key);
}finally {
lock.unlock();
}
}
public V get(Object key) {
try {
lock.lock();
return super.get(key);
} finally{
lock.lock();
}
}
public V put(K key, V value) {
try {
lock.lock();
return super.put(key, value);
} finally{
lock.lock();
}
}
public int size() {
try {
lock.lock();
return super.size();
} finally{
lock.unlock();
}
}
public void clear() {
try {
lock.lock();
super.clear();
}finally {
lock.unlock();
}
}
public Collection<Map.Entry<K, V>> getAll(){
try {
lock.lock();
return new ArrayList<Map.Entry<K,V>>(super.entrySet());
} finally {
lock.unlock();
}
}
}
LRU缓存实现2——HashMap + 双端链表
public class LRU2 {
private class Node{
Node prev;
Node next;
int key;
int value;
public Node(int key, int value) {
this.key = key;
this.value = value;
this.prev = null;
this.next = null;
}
}
private int capacity;
private HashMap<Integer, Node> map = new HashMap<>();
private Node head = new Node(-1, -1);
private Node tail = new Node(-1, -1);
public LRU2(int capacity) {
this.capacity = capacity;
this.head.next = this.tail;
this.tail.prev = this.head;
}
public int get(int key) {
if(!map.containsKey(key))
return -1;
Node curNode = map.get(key);
curNode.prev.next = curNode.next;
curNode.next.prev = curNode.prev;
moveToTail(curNode);
return map.get(key).value;
}
public void set(int key, int value) {
if(get(key) != -1) {
map.get(key).value = value;
return;
}
if(map.size() == capacity) {
map.remove(head.next.key);
head.next = head.next.next;
head.next.prev = head;
}
Node insertNode = new Node(key, value);
map.put(key, insertNode);
moveToTail(insertNode);
}
private void moveToTail(Node curNode){
curNode.next = tail;
tail.prev.next = curNode;
curNode.prev = tail.prev;
tail.prev = curNode;
}
}