1. 程式人生 > >LinkedHashMap實現LRU緩存算法

LinkedHashMap實現LRU緩存算法

entry 刪除 white 使用 sun 覆蓋 color init ron

LinkedHashMap的get()方法除了返回元素之外還可以把被訪問的元素放到鏈表的底端,這樣一來每次頂端的元素就是remove的元素 構造函數如下: public LinkedHashMap (int initialCapacity, float loadFactor, boolean accessOrder); initialCapacity 初始容量 loadFactor 加載因子,一般是 0.75f accessOrder false基於插入順序,true 基於訪問順序(get一個元素後,這個元素被加到最後,使用了LRU 最近最少被使用的調度算法)
import java.util.LinkedHashMap;
import java.util.Map; import java.util.concurrent.locks.ReentrantLock; /** * 該類是線程安全的帶有容量限制的LinkedHashMap * 超容量的元素采用LRU方式刪除 * 線程安全僅限於已經覆蓋的幾個方法,若有其他需要可自行添加 * 叠代操作不保證數據的一致性,即使remove方法是線程安全的也會拋ConcurrentModificationException */ public class LinkedMapLRU<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = -7911712053305433954L; private int capacity; private final ReentrantLock lock = new ReentrantLock(); public LinkedMapLRU(int capacity) { super(capacity, 0.75f, true); this.capacity = capacity; } @Override public
V put(K key, V value) { try { lock.lock(); return super.put(key, value); } finally { lock.unlock(); } } @Override public V get(Object key) { try { lock.lock(); return super.get(key); } finally { lock.unlock(); } } @Override public V remove(Object key) { try { lock.lock(); return super.remove(key); } finally { lock.unlock(); } } @Override public boolean removeEldestEntry(Map.Entry<K,V> eldest) { if(size() > capacity) {
System.out.println(eldest.getKey() +":" + eldest.getValue());
return true; } return false; } public void setMaxSize(int size) { this.capacity = size; } }

測試類:

LinkedMapLRU<Integer, Integer>  LRU = new LinkedMapLRU<Integer, Integer>(3);
        LRU.put(3, 1);
        LRU.put(6, 2);
        LRU.put(9, 3);
        LRU.get(3); //key=3移到頂部
        LRU.put(12, 4);
        LRU.put(15, 5);
        for(Map.Entry<Integer, Integer> entry : LRU.entrySet()) {
            System.out.println(entry.getKey() + " " +entry.getValue());
        }

測試結果:

6:2
9:3
3 1
12 4
15 5

LinkedHashMap實現LRU緩存算法