手写缓存之FIFO算法


前言

我们都知道为了减轻数据库的访问压力,有一个很好的办法就是添加本地缓存或者分布式缓存,那么大家了解缓存都有哪几种算法吗?我为大家介绍其中的一种算法——FIFO先进先出算法!

一、FIFO算法是什么?

FIFO先进先出算法其原理是,当缓存容器满了的时候想要插入一条新的对象,那么我们不得不删除最前面的那个对象,循环罔替。我们先来看是怎么实现的,最后我来告诉大家这种算法的不足之处!

二、使用步骤

1.先写一个接口类

在写FIFO(先进先出)缓存算法之前,我们先来拿个先案例简单实现一下缓存Cache。

代码如下(示例):

public interface Cache{
void putObject(Object key,Object value);
Object getObjec(key,value);
Object removeObjec(key,value);
void clear();
int size();
}

2.简单的Cache实现类

代码如下(示例):

/**
 * 简易Cache实现
 * 1)存储结构:散列表(基于JAVA中的hashmap存储)
 * 2)淘汰算法:没有(直到到内存溢出)
 * 3)线程安全:否
 * 4)缓存对对象的引用?强引用
 * 5)对象获取:浅拷贝(获取对象地址)
 */
public class perpetualCache implements Cache(){
 private HashMap<Object,Object> cache=new HashMap<>();
    @Override
    public void putObject(Object key, Object value) {
        cache.put(key, value);
    }

    @Override
    public Object getObject(Object key) {
        return cache.get(key);
    }

    @Override
    public Object removeObject(Object key) {
        return cache.remove(key);
    }

    @Override
    public void clear() {
        cache.clear();
    }

    @Override
    public int size() {
        return cache.size();
    }

    @Override
    public String toString() {
        return "PerpetualCache{" +
                "cache=" + cache.toString() +
                '}';
    }
}

下面我们把这个类作为基础去拓展FIFO算法,代码如下:

3.FIFO算法实现

/**
 * 构建先进先出Cache对象:缓存满了以后要优先淘汰最早放入的对象
 * 1)存储数据:基于hashmap
 * 2)淘汰算法:FIFO(关键点在于如何记录key的添加顺序)
 *
 */
public class FifoCache implements Cache{
/**关联Cache对象-找到可以存储数据的基层对象*/
    private Cache cache;
    /**定义Cache的最大容量*/
    private int maxCap;
    /**通过队列记录key的添加顺序,Deque是JAVA中的双端队列*/
    private Deque<Object> keyOrders;
    public FifoCache(Cache cache, int maxCap) {
        this.cache = cache;
        this.maxCap = maxCap;
        this.keyOrders=new LinkedList<>();
    }
    @Override
    public void putObject(Object key, Object value) {
        //1.记录key的顺序(添加在队列的尾部)
        keyOrders.addLast(key);
        //2.判断容器是否已满,满了则移除
        if(keyOrders.size()>maxCap){
            Object firstKey = keyOrders.removeFirst();
            //从cache中清除指定key对应的对象
            cache.removeObject(firstKey);
        }
        //3.向cache添加数据
        cache.putObject(key, value);
    }

    @Override
    public Object getObject(Object key) {
        return cache.getObject(key);
    }
    @Override
    public Object removeObject(Object key) {
        //1.从Cache中移除对象
        Object object = cache.removeObject(key);
        //2.从队列移除key
        keyOrders.remove(key);
        return object;
    }
    @Override
    public void clear() {
          cache.clear();
          keyOrders.clear();
    }

    @Override
    public int size() {
        return cache.size();
    }

    @Override
    public String toString() {
        return "FifoCache{" +
                "cache=" + cache.toString() +
                ", maxCap=" + maxCap +
                ", keyOrders=" + keyOrders +
                '}';
    }

    public static void main(String[] args) {
        Cache cache=new FifoCache(//负责添加算法
                         new PerpetualCache(),//负责存数据
                           3);
        //如上语句其实是一种装饰模式的实现(思考:new BufferedReader(new FileReader(file)))
        cache.putObject("A", 100);
        cache.putObject("B", 200);
        cache.putObject("C", 300);
        cache.putObject("D", 400);
        cache.putObject("E", 500);
        System.out.println(cache);
    }
}

4. 运行效果

可以看出,最后就只剩C,D,E,A和B都被删除掉了! 


总结

这种算法的缺点在于:FIFO算法对于一些内存中访问频率比较高,但是放入的时间又比较早的对象而言,命中率会比较率。所以这种算法使用的越来越少了,近些年比较流行的缓存算法为Lru算法,等我完全吃透Lru算法再来为大家讲解哦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值