-
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