中都

风习袅袅,盈水展千华,飞檐亭角清铃响。犹记当初,你回眸莞尔,一笑倾城百日香。

博客园 首页 新随笔 联系 订阅 管理

一、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]
-----------------------------------------------

  

posted on 2021-04-01 22:07  中都  阅读(135)  评论(0)    收藏  举报
Live2D