java 自定义 LRU(最近最少使用)策略 实现 缓存机制

1. java提供了一个简单的方式实现LRU:  LinkedHashMap

 

2. 自定义实现

LRU至少需要两个主要操作: 添加(add)和搜索(search)

public class LRUCache {
    private Map<String, CacheEntry> map;
    private CacheEntry head , tail;
    private int maxSize;
    public LRUCache(int maxSize){
        if(maxSize < 1){
            throw new IllegalArgumentException("Cache maxSize has to be at least 1");
        }
        this.map = new HashMap<String, CacheEntry>();
        head = new CacheEntry("head","");
        tail = new CacheEntry("tail", "");
        head.setNext(tail);
        tail.setPrev(head);
        this.maxSize = maxSize;
    }
    public void add(String key, String value){
        CacheEntry cacheEntry = map.get(key);
        if(cacheEntry == null){
            cacheEntry = new CacheEntry(key, value);
            if(map.size() == maxSize){
                //缓存达到最大数目
                //删除最老的条目
                CacheEntry deleteEntry = tail.getPrev();
                //从map中移除
                map.remove(deleteEntry.getKey());
                //从队列中移除
                remove(deleteEntry);
            }
            //添加条目到队列
            addFront(cacheEntry);
            //添加到map
            map.put(key, cacheEntry);
        }else{
            //更新值
            cacheEntry.setValue(value);
            //访问条目
            accessed(cacheEntry);
        }
    }

    public String search(String key){
        CacheEntry entry = map.get(key);
        if(entry == null){
            return null;
        }
        accessed(entry);
        return entry.getValue();
    }
    //打印缓存内容
    public void print(){
        CacheEntry entry = head.getNext();
        while(entry != tail){
            System.out.println("{" + entry.getKey() + ":" + entry.getValue() + "}");
            entry = entry.getNext();
        }
        System.out.println();
    }

    public void accessed(CacheEntry entry) {
        if(entry.getPrev() != head){
            remove(entry);
            addFront(entry);
        }
    }

    private void addFront(CacheEntry entry) {
        //在队列的头部添加条目
        CacheEntry nextEntry = head.getNext();
        head.setNext(entry);
        entry.setPrev(head);
        entry.setNext(nextEntry);
        if(nextEntry != null){
            nextEntry.setPrev(entry);
        }
    }

    private void remove(CacheEntry entry) {
        if(entry == head || entry == tail){
            return;//错误
        }
        entry.getPrev().setNext(entry.getNext());
        if(entry.getNext() != null){
            entry.getNext().setPrev(entry.getPrev());
        }
    }
}
/**
 * Created by admin on 2018/3/30.
 */
public class CacheEntry {
    private CacheEntry prev, next;
    private String key, value;
    CacheEntry(String key, String value){
        this.key = key;
        this.value = value;
    }

    public CacheEntry getPrev() {
        return prev;
    }

    public void setPrev(CacheEntry prev) {
        this.prev = prev;
    }

    public CacheEntry getNext() {
        return next;
    }

    public void setNext(CacheEntry next) {
        this.next = next;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

原文地址:https://www.cnblogs.com/rocky-fang/p/8676318.html

时间: 2024-10-20 21:55:13

java 自定义 LRU(最近最少使用)策略 实现 缓存机制的相关文章

java框架篇---hibernate之缓存机制

一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 二.what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存. 1.Hibernate一级缓存又称为“Session的

Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过Session持久化操作,缓存中存在这个对象的数据为持久状态并且数据库中存在这个对象对应的数据为持久状态这个时候有OID. 游离状态:当Session关闭,缓存中不存在这个对象数据而数据库中有这个对象的数据并且有OID为游离状态. 注:OID为了在系统中能够找到所需对象,我们需要为每一个对象分配一个

深入 Java自定义注解

我们在使用Spring框架的时候,会经常使用类似:@Autowired 这样的注解.我们也可以自己定义一些注解.Java的注解主要在包:java.lang.annotation中实现. 1. 元注解 什么是元注解?你可以这样理解,元注解是自定义注解的注解.元注解主要包含4个.他们主要在java.lang.annotation中可以找到.我们自己要创建注解的时候必须要用到这些元注解.所以必须彻底理解这四个元注解的含义. 1. @Documented 2. @Inherited 3. @Retent

三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)

目录 Hibernate生成策略与缓存策略 主键生成策略 主键分类 主键的生成策略 持久化 什么是持久化 什么是持久化类 持久化类编写规则 持久化类的划分 三种状态区分 持久态对象特征 一级缓存 什么是缓存 一级缓存 一级缓存特点 一级缓存内部结构 事务管理 什么是事务 事务特性 事务的隔离级别 Hibernate设置事务的隔离级别 事务业务层连接 Hibernate生成策略与缓存策略 主键生成策略 主键分类 自然主键 主键本身就是表中的一个字段 实体中一个具体的属性,对象本身唯一的特性 创建一

Kafka 自定义指定消息partition策略规则及DefaultPartitioner源码分析

Kafka 自定义指定消息partition策略规则及DefaultPartitioner源码分析 一.概述 kafka默认使用DefaultPartitioner类作为默认的partition策略规则,具体默认设置是在ProducerConfig类中(如下图) 二.DefaultPartitioner.class 源码分析 1.类关系图 2.源码分析 public class DefaultPartitioner implements Partitioner { //缓存map key->to

【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qOMO0LIdA47j3RjhbCWUEQ 作者:李志刚 导语 Http 缓存机制作为 web 性能优化的重要手段,对从事 Web 开发的小伙伴们来说是必须要掌握的知识,但最近我遇到了几个缓存头设置相关的题目,发现有好几道题答错了,有的甚至在知道了正确答案后依然不明白其原因,可谓相当的郁闷呢!!为了确认下是否只是自己理解不深,我特意请教了其他几位小伙

Java缓存学习之三:CDN缓存机制

CDN是什么? 关于CDN是什么,此前网友详细介绍过. CDN是Content Delivery Network的简称,即"内容分发网络"的意思.一般我们所说的CDN加速,一般是指网站加速或者用户下载资源加速. 举个通俗的例子: 谈到CDN的作用,可以用8年买火车票的经历来形象比喻:8年前,还没有火车票代售点一说,12306.cn更是无从说起.那时候火车票还只能在火车站的售票大厅购买,而我所住的小县城并不通火车,火车票都要去市里的火车站购买,而从县城到市里,来回就是4个小时车程,简直就

Java缓存学习之二:浏览器缓存机制

浏览器端的九种缓存机制介绍 浏览器缓存是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户.浏览器端缓存的机制种类较多,总体归纳为九种,这里详细分析下这九种缓存机制的原理和使用场景.打开浏览器的调试模式->resources左侧就有浏览器的8种缓存机制. 一.http缓存 http缓存是基于HTTP协议的浏览器文件级缓存机制.即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从

java自定义注解类

一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Tar