当前位置:首页 > 科技  > 软件

面试官:如何设计和实现一个带过期时间的本地缓存?

来源: 责编: 时间:2024-04-09 09:07:09 102观看
导读在日常开发中有很多这样的场景:有一些业务系统的配置信息,数据量不大,修改频率不高,但是访问很频繁。如果每次程序都从数据库或集中式缓存中获取,受限于硬盘 I/O性能、远程网络访问限制等,程序的执行效率不高。在这样的业务

在日常开发中有很多这样的场景:有一些业务系统的配置信息,数据量不大,修改频率不高,但是访问很频繁。如果每次程序都从数据库或集中式缓存中获取,受限于硬盘 I/O性能、远程网络访问限制等,程序的执行效率不高。在这样的业务场景中,我们可以通过本地缓存来提升数据访问的效率。pUH28资讯网——每日最新资讯28at.com

今天我们来基于ConcurrentHashMap与ScheduledThreadPoolExecutor来实现一个线程安全的本地缓存:LocalCache。在LocalCache中支持永久缓存与临时缓存,永久缓存的数据一直有效,临时缓存的数据在指定时间到期之后会自动从缓存中移出。pUH28资讯网——每日最新资讯28at.com

LocalCache提供了数据安全的增、删、改、查功能,具体方法如下所示:pUH28资讯网——每日最新资讯28at.com

方法名称
pUH28资讯网——每日最新资讯28at.com

方法说明
pUH28资讯网——每日最新资讯28at.com

put(String key , V value)
pUH28资讯网——每日最新资讯28at.com

向缓存中插入数据,数据永久有效
pUH28资讯网——每日最新资讯28at.com

put(String key , V value , int seconds)
pUH28资讯网——每日最新资讯28at.com

向缓存中插入数据,数据根据设定的时间生效,时间到期会从缓存中移出
pUH28资讯网——每日最新资讯28at.com

containKey(String key)
pUH28资讯网——每日最新资讯28at.com

判断缓存中是否包含对应的key
pUH28资讯网——每日最新资讯28at.com

get(String key)
pUH28资讯网——每日最新资讯28at.com

根据key从缓存中获取数据
pUH28资讯网——每日最新资讯28at.com

remove(String key)
pUH28资讯网——每日最新资讯28at.com

移出缓存中对应key的数据
pUH28资讯网——每日最新资讯28at.com

shutdownNow()
pUH28资讯网——每日最新资讯28at.com

关闭缓存池
pUH28资讯网——每日最新资讯28at.com

1. 设计原理

LocalCache主要由3个部分组成:数据缓存、数据超时时间、数据清理任务。数据缓存和数据超时时间都采用ConcurrentHashMap来存储数据,数据超时时间中Key为数据存储的键,value是数据的时间戳。数据清理任务采用ScheduledThreadPoolExecutor实现任务调度,默认的任务线程数为1,这样可以避免多线程带来的并发修改问题,同时线程都是内存操作,这样单线程同样具备高性能。pUH28资讯网——每日最新资讯28at.com

本地缓存的设计如下图所示:pUH28资讯网——每日最新资讯28at.com

图片图片pUH28资讯网——每日最新资讯28at.com

每次项缓存中插入数据时,LocalCache首先会将数据插入到ConcurrentHashMap中。然后判断有没有设置超时时间,如果有超时时间,LocalCache会将失效时间插入到ConcurrentHashMap中,并创建数据清理任务,之后任务提交到ScheduledThreadPoolExecutor线程池中。pUH28资讯网——每日最新资讯28at.com

每次从缓存中查询数据,LocalCache会直接从ConcurrentHashMap中读取数据。pUH28资讯网——每日最新资讯28at.com

定时任务线程池会按照超时时间来触发数据清理任务,数据清理任务会从数据时长的缓存池中获取Key对应的时间,判断当前Key对应的数据是否已经到期了。如果数据已经到期了,LocalCache会调用remove方法将数据从缓存池中移除。pUH28资讯网——每日最新资讯28at.com

2. 实现方案

LocalCache作为本地缓存的接口,定义了数据插入、数据删除、数据查询的相关接口方法。DefaultLocalCache 定义了两个ConcurrentHashMap变量:dataMap和timeOutMap。dataMap用来缓存数据信息,timeOutMap用来存储数据失效的时间戳,同时还定义了数据清理任务ClearTask,ClearTask负责将过期的数据从dataMap中移除。UML图如下所示:pUH28资讯网——每日最新资讯28at.com

图片图片pUH28资讯网——每日最新资讯28at.com

3. 代码展示

3.1 接口定义

public interface LocalCache<V> {    /**     * 插入数据,数据永久有效     */    boolean put(String key, V value);    /**     * 插入数据,在指定时间内生效     */    boolean put(String key, V value, int seconds);    /**     * 是否包含指定的key     */    boolean containKey(String key);    /**     * 获取指定Key的值     */    V get(String key);    /**     * 从缓存中移除key对应的数据     */    void remove(String key);    void shutdownNow();}

在接口LocalCache中定义了两个数据插入的put接口:一个没有到期时间,另一个有到期时间。没有到期时间表示数据永久有效,有到期时间的数据会在到期后从缓存中移除。pUH28资讯网——每日最新资讯28at.com

接口实现

在接口实现DefaultLocalCache内部定义了三个常量:缓存的默认大小DEFAULT_CAPACITY、最大容量MAX_CAPACITY、定时线程池的大小DEFAULT_THREAD_SIZE。核心代码如下:pUH28资讯网——每日最新资讯28at.com

public class DefaultLocalCache<V> implements LocalCache<V> {    // 默认容量    private static final int DEFAULT_CAPACITY = 1024;    private static final int MAX_CAPACITY = 100000;    private static final int DEFAULT_THREAD_SIZE = 1;    private final int maxSize;    //数据map    private volatile ConcurrentHashMap<String,V> dataMap;    //过期时间    private final ConcurrentHashMap<String,Long> timeOutMap;    //定时任务    private final ScheduledExecutorService executorService;    public DefaultLocalCache() {        maxSize = MAX_CAPACITY;        dataMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);        timeOutMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);        executorService = new ScheduledThreadPoolExecutor(DEFAULT_THREAD_SIZE) ;    }    public DefaultLocalCache(int size) {        maxSize = size;        dataMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);        timeOutMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);        executorService = new ScheduledThreadPoolExecutor(DEFAULT_THREAD_SIZE) ;    }    @Override    public boolean put(String key, V value) {        //检查容量        if(checkCapacity()){            dataMap.put(key,value);            return true;        }        return false;    }    @Override    public boolean put(String key, V value, int seconds) {        if(checkCapacity()){            dataMap.put(key,value);            if(seconds >= 0){                timeOutMap.put(key,getTimeOut(seconds));                ClearTask task = new ClearTask(key);                executorService.schedule(task, seconds, TimeUnit.SECONDS);            }        }        return false;    } ......    class ClearTask implements Runnable{        private String key;        public ClearTask(String key){            this.key = key;        }        @Override        public void run() {            //判断缓存中是否有key            if(timeOutMap.contains(key)){                //获取失效时间                Long expire = timeOutMap.get(key);                //如果失效时间大于0,并且比当前时间小,则删除缓存                if(expire > 0){                    long now = System.currentTimeMillis();                    if(now >= expire){                        remove(key);                    }                }            }        }    }}

在LocalCache的默认实现DefaultLocalCache中,基于ConcurrentHashMap与ScheduledThreadPoolExecutor结合使用,使得LocalCache支持永久缓存与临时缓存两种能力。pUH28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-82181-0.html面试官:如何设计和实现一个带过期时间的本地缓存?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: JVM类加载:如何手写自定义类加载器,命名空间详解

下一篇: 四万字102道Java多线程经典面试题

标签:
  • 热门焦点
  • 帅气纯真少年!日本最帅初中生选美冠军出炉

    帅气纯真少年!日本最帅初中生选美冠军出炉

    日本第一帅哥初一生选美大赛冠军现已正式出炉,冠军是来自千叶县的宗田悠良。日本一直热衷于各种选美大赛,从&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌在KDD 2023发表了一篇工作,探索了推荐系统ranking模型的训练稳定性问题,分析了造成训练稳定性存在问题的潜在原因,以及现有的一些提升模型稳定性方法的不足,并提出了一种新
  • 使用LLM插件从命令行访问Llama 2

    使用LLM插件从命令行访问Llama 2

    最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2。这是一项非常重要的进展:Llama 2可免费用于研究和商业用途。(几小时前,swyy发现它已从LLaMA 2更名为Lla
  • 为什么你不应该使用Div作为可点击元素

    为什么你不应该使用Div作为可点击元素

    按钮是为任何网络应用程序提供交互性的最常见方式。但我们经常倾向于使用其他HTML元素,如 div span 等作为 clickable 元素。但通过这样做,我们错过了许多内置浏览器的功能。
  • 自律,给不了Keep自由!

    自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 大厂卷向扁平化

    大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 消息称小米汽车开始筛选交付中心:需至少120个车位

    消息称小米汽车开始筛选交付中心:需至少120个车位

    IT之家 7 月 7 日消息,日前,有微博简介为“汽车行业从业者、长三角一体化拥护者”的微博用户 @长三角行健者 发文表示,据经销商集团反馈,小米汽车目前
  • OPPO K11搭载长寿版100W超级闪充:26分钟充满100%

    OPPO K11搭载长寿版100W超级闪充:26分钟充满100%

    据此前官方宣布,OPPO将于7月25日也就是今天下午14:30举办新品发布会,届时全新的OPPO K11将正式与大家见面,将主打旗舰影像,和同档位竞品相比,其最大的卖
  • 上海举办人工智能大会活动,建设人工智能新高地

    上海举办人工智能大会活动,建设人工智能新高地

    人工智能大会在上海浦江两岸隆重拉开帷幕,人工智能新技术、新产品、新应用、新理念集中亮相。8月30日晚,作为大会的特色活动之一的上海人工智能发展盛典人工
Top