一、FIFO缓存置换算法
先进先出置换算法,只需要用一个固定大小的队列,一边添加新的页(如果需要添加的页已经在队列里面,直接跳过),一边淘汰旧的页,即可;
/**
* @ClassName: FIFO
* @Author: 中都
* @Date: 2020/5/24 18:37
* @Description: 先进先出算法
*/
public class FIFO {
private LinkedList<Integer> list = new LinkedList<>();
private int maxSize = 10;
public FIFO(int maxSize) {
this.maxSize = maxSize;
}
public void add(int x) {
//已经满了,添加一个到头上去,把后面的删除
if(list.size() == maxSize) {
list.removeLast();
}
list.addFirst(x);
}
public void show() {
System.out.println(list);
}
}
public static void main(String[] args) {
FIFO fifo = new FIFO(3);
for (int i = 1; i <= 10; i++) {
fifo.add(i);
fifo.show();
}
}
[1] [2, 1] [3, 2, 1] [4, 3, 2] [5, 4, 3] [6, 5, 4] [7, 6, 5] [8, 7, 6] [9, 8, 7]、 [10, 9, 8]
二、LRU缓存置换算法
最近最久未使用缓存置换算法,也需要一个固定大小的队列,前边添加新的页(如果需要添加的页在队列里面,直接将其提取的最前面去),一边淘汰旧的页,即可;


注意上面那个图,节点五下来应该是节点1,过程应该是把节点五调整到前面来,而不是让节点五和节点1互换;
/**
* @ClassName: LRU
* @Author: 中都
* @Date: 2020/5/24 18:37
* @Description: 最近最久未使用算法
*/
public class LRU {
private LinkedList<Integer> list = new LinkedList<>();
private int maxSize = 0;
public LRU(int maxSize) {
this.maxSize = maxSize;
}
public void add(int x) {
//如果队列已经到达最大容量值
if(list.size() == maxSize) {
//如果当前要添加的已经在队列里面,把他提取到前面来
if(list.contains(x)) {
list.remove(Integer.valueOf(x));
}else {
//如果当前要添加的不在队列里面,淘汰掉最后的那个
list.removeLast();
}
}
//添加新的到队列头
list.addFirst(x);
}
public void show() {
System.out.println(list);
}
}
public static void main(String[] args) {
LRU lru = new LRU(3);
lru.add(1);
lru.show();
lru.add(2);
lru.show();
lru.add(3);
lru.show();
lru.add(4);
lru.show();
lru.add(3);
lru.show();
lru.add(4);
lru.show();
lru.add(5);
lru.show();
lru.add(3);
lru.show();
}
[1] [2, 1] [3, 2, 1] [4, 3, 2] [3, 4, 2] [4, 3, 2] [5, 4, 3] [3, 5, 4]
三、LFU缓存置换算法
最近最少使用缓存置换算法,这个麻烦一点,因为要统计哪个用的最少,需要统计使用频率,并且也有可能出现使用频率相同且都最低的情况,这种情况下需要按照先进先出算法淘汰页面,也就还需要多个对列用来记录相同频率的节点的进入顺序;


/**
* @ClassName: LFU
* @Author: 中都
* @Date: 2020/5/24 18:37
* @Description: 最近最少使用算法
*/
public class LFU {
//记录出现该频率(key)的值的集合(value),value即不同的频率队列
private HashMap<Integer,LinkedList<Integer>> hashMap = new HashMap<>();
//记录当前队列中存在的元素及顺序
private LinkedList<Integer> list = new LinkedList<>();
//记录队列允许存放元素的最大值
private int maxSize = 0;
public LFU(int maxSize) {
this.maxSize = maxSize;
}
public void add(int x) {
//如果需要添加的元素已经在队列中了,只需要调整其频率队列即可
if(list.contains(x)) {
int f = 0;
Iterator<Map.Entry<Integer, LinkedList<Integer>>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, LinkedList<Integer>> next = iterator.next();
int key = next.getKey();
LinkedList<Integer> value = next.getValue();
if(value.contains(x)) {
value.remove(Integer.valueOf(x)); //将其从旧频率队列中删除
f = key+1;
break;
}
}
//加入到新的频率队列
if(hashMap.containsKey(f)) {
hashMap.get(f).addLast(x);
}else {
LinkedList<Integer> list1 = new LinkedList<>();
list1.addLast(x);
hashMap.put(f,list1);
}
}else {
//已经满了,需要淘汰,找到出现频率最低的频率队列,将其出现最早的数据删除,并将记录队列的对应数据也删除
if(list.size() == maxSize) {
int f = 0; //记录被删除的那个数
Iterator<Map.Entry<Integer, LinkedList<Integer>>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, LinkedList<Integer>> next = iterator.next();
LinkedList<Integer> value = next.getValue();
if(value.size() > 1) {
f = value.removeFirst();//当前频率队列有多个值,删除掉最先出现的那个值
break;
}else {
f = value.getFirst();
iterator.remove(); //当前队列只有1值,连着节点一块删除
break;
}
}
//将这个数在记录队列中也删除
list.remove(Integer.valueOf(f));
}
//淘汰完成,添加新值
list.addFirst(x);
//到了这儿,肯定队列和集合中都没有这个新值(即第一次出现),因为那样的话走第一个if语句
if(hashMap.containsKey(1)) {
hashMap.get(1).addLast(x);
}else {
LinkedList<Integer> list1 = new LinkedList<>();
list1.addLast(x);
hashMap.put(1,list1);
}
}
}
public void show() {
System.out.println(list);
Iterator<Map.Entry<Integer, LinkedList<Integer>>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, LinkedList<Integer>> next = iterator.next();
System.out.println(next.getKey()+" "+next.getValue());
}
System.out.println("-----------------------------------------------");
}
}
public static void main(String[] args) {
LFU lfu = new LFU(3);
lfu.add(1);
lfu.show();
lfu.add(2);
lfu.show();
lfu.add(3);
lfu.show();
lfu.add(4);
lfu.show();
lfu.add(3);
lfu.show();
lfu.add(4);
lfu.show();
lfu.add(5);
lfu.show();
lfu.add(3);
lfu.show();
}
[1] 1 [1] ----------------------------------------------- [2, 1] 1 [1, 2] ----------------------------------------------- [3, 2, 1] 1 [1, 2, 3] ----------------------------------------------- [4, 3, 2] 1 [2, 3, 4] ----------------------------------------------- [4, 3, 2] 1 [2, 4] 2 [3] ----------------------------------------------- [4, 3, 2] 1 [2] 2 [3, 4] ----------------------------------------------- [5, 4, 3] 1 [5] 2 [3, 4] ----------------------------------------------- [5, 4, 3] 1 [5] 2 [4] 3 [3] -----------------------------------------------
浙公网安备 33010602011771号