請用Java設計一個Least Recently Used (LRU) 緩存

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); } } 線程

相關文章
相關標籤/搜索