本地缓存之LIFO、LRU、FIFO、LFU实现

16 篇文章 0 订阅
13 篇文章 0 订阅

LIFO算法

后进先出,利用栈实现

实现

    @Test
    public void stackDemo(){
        Stack<Integer> stack = new Stack<>();
        for (int i = 1; i < 4; ++i){
            stack.add(i);
        }
        ArrayList<Integer> list = new ArrayList<>();
        while (!stack.isEmpty()){
            list.add(stack.pop());
        }
        Assertions.assertEquals(Arrays.asList(3, 2, 1), list);
    }

LRU算法

全称 The Least Recently Used,最近最久未使用算法,是一种常见的缓存算法,在很多分布式缓存系统(Redis、Memcached等)使用。

算法核心

如果一个数据在最近一段时间没有被访问到,那么可以认为在将来它被访问的可能性也很小。
当缓存满时,将最久未使用的数据置换掉,也就是首先淘汰最长时间未被使用的

实现

最简单做法是用数组+时间戳,不过效率太低,因此我们用双向链表LinkedList + HashMap 实现(链表用来表示位置,哈希表用来存储和查找),在Java中对应的数据结构就是LinkedHashMap

import java.util.LinkedHashMap;

/**
 * @author weijie
 * 利用最近最少未使用算法实现缓存
 * 2019年6月23日
 */
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
	private static final long serialVersionUID = 1L;
	private final int SIZE;
    public LRUCache(int size) {
        /** int initialCapacity, float loadFactor, boolean accessOrder
         * 这3个分别表示容量,加载因子和是否启用LRU规则
         */
        super(size, 0.75f, true);
        SIZE = size;
    }
    @Override
    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
        return size() > SIZE;
    }
    
    public static void main(String[] args) {
    	int size = 3;
		LRUCache<Integer, Integer> cache = new LRUCache<>(size);
		for(int i = 0; i < 3; i++) {
			cache.put(i, i);
		}
		cache.get(1);
		cache.get(2);
		cache.put(4, 4);
		System.out.println(cache.values());
	}
}

输出:[1, 2, 4]
3由于未访问自动删除,让4插入进去

FIFO算法

FIFO 算法是一种比较容易实现的算法。它的思想是先进先出(FIFO,队列),这是最简单、最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小。空间满的时候,最先进入的数据会被最早置换(淘汰)掉。

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author weijie
 *
 * 2019年6月23日
 * @param <V>
 */
public class FIFOCache<K, V> extends LinkedHashMap<K, V> {

	class FIFODemo<K, V> extends LinkedHashMap<K, V>{

	}


	private static final long serialVersionUID = 1L;
	private final int SIZE;
    public FIFOCache(int size) {
        super();
        SIZE = size;
    }
    /**
     *  重写淘汰机制
     * @param eldest
     * @return
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        //如果缓存存储达到最大值删除最后一个
        return size() > SIZE;
    }
    
    public static void main(String[] args) {
    	int size = 10;
		FIFOCache<Integer,String> fifoCache = new FIFOCache<Integer, String>(size);
		for(int i = 0; i < 16; i++) {
			fifoCache.put(i, ((char) (i + 65)) + "");
		}
		System.out.println(fifoCache);
	}
}

输出:{6=G, 7=H, 8=I, 9=J, 10=K, 11=L, 12=M, 13=N, 14=O, 15=P}

LFU算法

淘汰一定时期内被访问次数最少的
LRU关键是看页面最后一次被使用到发生调度的时间长短
LFU关键是看一定时间段内页面被使用的频率!

参考:
https://blog.csdn.net/summerhust/article/details/6867171
https://www.cnblogs.com/hongdada/p/10406902.html

LRU和LFU优秀文章链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值