请用Java设计一个Least Recently Used (LRU) 缓存

LRU介绍:LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的,

思路介绍:

可以使用两个标准的数据结构来实现,Map和Queue。因为需要支持多线程,需要使用实现了java.utili.concurrent.*的Map和Queue。

主要思路是使用一个Queue来维护FIFO和Map来对数据进行排序,当向缓存添加新的元素时,共有以下三种可能

1. 如果该元素已经在Cache中存在(Map),我们会从queue中删除改元素并将其添加到queue的第一个位置。

2. 如果缓存已满无法新增新的元素,我们会从queue和Map中删除最后面的那个元素并把新元素添加进来。

3. 同时在Map和Queue中增加新的元素

简单的代码如下:

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值