LRU介紹:LRU是Least Recently Used的縮寫,即最少使用頁面置換算法,是爲虛擬頁式存儲管理服務的,java
思路介紹:
算法
可以使用兩個標準的數據結構來實現。Map和Queue。因爲需要支持多線程。需要使用實現了java.utili.concurrent.*的Map和Queue。緩存
主要思路是使用一個Queue來維護FIFO和Map來對數據進行排序。當向緩存加入新的元素時,共同擁有下面三種可能數據結構
1. 假設該元素已經在Cache中存在(Map),咱們會從queue中刪除改元素並將其加入到queue的第一個位置。多線程
2. 假設緩存已滿沒法新增新的元素,咱們會從queue和Map中刪除最後面的那個元素並把新元素加入進來。post
3. 同一時候在Map和Queue中添加新的元素this
簡單的代碼例如如下:spa
package cn.kge.comdemo; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; public class LRUCache<K,V> { /** * LRU緩存的最大容量. */ private final int capacity; //用來保持近期使用的元素的Queue. private ConcurrentLinkedQueue<K> queue; private ConcurrentHashMap<K, V> map; /** * 初始化LRU緩存 * @param capacity */ public LRUCache(final int capacity) { this.capacity = capacity; this.queue = new ConcurrentLinkedQueue<K>(); this.map = new ConcurrentHashMap<K, V>(capacity); } /** * 檢查該元素釋放在緩存中存在,假設不存在則返回null * @param key * @return */ public V get(final K key) { return map.get(key); } /** * 將元素加入到LRU緩存。假設Key已存在,則將其放到緩存的第一位置 * @param key * @param value * @throws NullPointerException */ public synchronized void put(final K key, final V value) { if(key == null || value == null) { throw new NullPointerException(); } if (map.containsKey(key)) { queue.remove(key); } while (queue.size() >= capacity) { K expiredKey = queue.poll(); if (expiredKey != null) { map.remove(expiredKey); } } queue.add(key); map.put(key, value); } } 線程