-
LRU 是 Least Recently Used 的缩写,意思是 最近最少使用 。LRU 缓存就是使用这种原理实现,就是缓存一定的数据,超过设定的最大值以后就移除过期的数据。
-
解决方案:可以使用两个数据结构实现一个LRU缓存。
1)使用双向链表实现的队列,队列的最大容量为缓存的大小。在使用的过程中把最近使用的页面移动到队列头,最近没有使用的放在后面。
2)使用一个哈希表,把页号最为键,把缓存在队列中的节点地址作为值。
具体代码如下:
public class LRU {
// 存储值
private ArrayDeque<Integer> queue = new ArrayDeque<>();
private HashSet<Integer> hashSet = new HashSet<>();
// 缓存大小
private int cacheSize;
public LRU(int cacheSize) {
this.cacheSize = cacheSize;
}
// 判断队列是否已满
private boolean isQueueFull() {
return queue.size() == cacheSize;
}
private void enqueue(int pageNum) {
if (isQueueFull()) {
hashSet.remove(queue.getLast());
// 移除最后一个 如果使用 queue.removeLast(); 如果是 null 会抛出异常 使用 queue.pollLast();如果是 null 则返回 null
queue.pollLast();
}
queue.addFirst(pageNum);
hashSet.add(pageNum);
}
public void accessPage(int pageNum) {
if (!hashSet.contains(pageNum)) {
// 如果没有缓存则添加进去
enqueue(pageNum);
} else if (pageNum != queue.getFirst()) {
// 如果在缓存中则移动到队首
queue.remove(pageNum);
queue.addFirst(pageNum);
}
}
public void printQueue() {
while (!queue.isEmpty()) {
System.out.println(queue.pop() + " ");
}
}
}
- 使用方式
@Test
public void test2() {
LRU lru = new LRU(3);
lru.accessPage(1);
lru.accessPage(2);
lru.accessPage(3);
lru.accessPage(4);
lru.accessPage(5);
lru.accessPage(6);
lru.accessPage(6);
lru.accessPage(5);
lru.printQueue();
}
运行结果为:5 6 4