【缓存服务】⭐️自定义实现一个简易的数据缓存

embedded/2024/10/9 17:26:06/

目录

🍸前言

🍻手写缓存服务

        (1)缓存实体类

        (2)缓存工具类

        (3)测试缓存服务

🍷已有的缓存工具

🍹章末


🍸前言

        俗话说 有轮子不用 就是玩

        开个玩笑,通过手写缓存服务可以帮助我们更好的了解,缓存需要哪些东西,比如内存的持久化,还有支持缓存的数据自动过期清除。对于简单的数据缓存,可以自行编写一套缓存服务,缓存通常的使用如下:

🍻手写缓存服务

        (1)缓存实体类

        要实现缓存功能,首先要有对象接收数据,数据包含的基本内容有键值和过期时间等,代码如下:

java">import lombok.Data;/*** @author ben.huang*/
@Data
public class CacheEnity {/*** 缓存的key值*/private String key;/*** 缓存的value值*/private Object value;/*** 缓存的过期时间*/private Long expireTime;
}
        (2)缓存工具类

        接收数据的对象有了之后,需要有一个操作缓存的工具,包括存放数据,获取数据,删除数据,定期清理已过期缓存等操作,定期清理操作通过创建一个定时线程任务每隔一段时间查询筛除已过期的数据,工具类代码如下:

java">import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** @author ben.huang*/
public class CacheUtil {/*** 缓存容器*/private final static Map<String, CacheEnity> CACHE_MAP = new ConcurrentHashMap<>();private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();/*** 存放缓存,过期时间为当前时间加上传入的过期时间** @param key* @param value* @param expireTime 过期时间(毫秒)*/public static void put(String key, Object value, long expireTime) {CacheEnity cacheEnity = new CacheEnity();cacheEnity.setKey(key);cacheEnity.setValue(value);if (expireTime > 0) {Long expire = System.currentTimeMillis() + Duration.ofSeconds(expireTime).toMillis();cacheEnity.setExpireTime(expire);}CACHE_MAP.put(key, cacheEnity);}/*** 默认永不过期的存放** @param key* @param value*/public static void put(String key, Object value) {put(key, value, 0);}/*** 缓存获取,没有则返回null** @param key* @return*/public static Object get(String key) {if (CACHE_MAP.containsKey(key)) {return CACHE_MAP.get(key).getValue();}return null;}/*** 删除缓存** @param key*/public static void remove(String key) {CACHE_MAP.remove(key);}/*** 定期清理操作,筛掉已过期的数据*/public static void clearCache() {//没有数据直接返回,提升性能if (CACHE_MAP.size() == 0) {return;}//过期时间不为空,并且已经过期CACHE_MAP.entrySet().removeIf(entry -> entry.getValue().getExpireTime() != null && entry.getValue().getExpireTime() <= System.currentTimeMillis());}//注册一个定时线程任务,服务启动1秒之后,每隔500毫秒执行一次清理方法static {executor.scheduleAtFixedRate(CacheUtil::clearCache, 1000, 500, TimeUnit.MILLISECONDS);}
}
        (3)测试缓存服务

         存放三个数据,第一个数据设置过期时间 3 秒,第二个数据过期时间设置 6 秒,第三个数据不设置过期时间,也就是永不过期,然后分多次时间查询,结果如下:

java">public class TestCache {public static void main(String[] args) {CacheUtil.put("user1","张山",3);CacheUtil.put("user2","李斯",6);CacheUtil.put("user3","汪芜");System.out.println("第一次查询 user1:"+CacheUtil.get("user1"));System.out.println("第一次查询 user2:"+CacheUtil.get("user2"));System.out.println("第一次查询 user3:"+CacheUtil.get("user3"));try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("\n第二次查询 user1:"+CacheUtil.get("user1"));System.out.println("第二次查询 user2:"+CacheUtil.get("user2"));System.out.println("第二次查询 user3:"+CacheUtil.get("user3"));try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("\n第三次查询 user1:"+CacheUtil.get("user1"));System.out.println("第三次查询 user2:"+CacheUtil.get("user2"));System.out.println("第三次查询 user3:"+CacheUtil.get("user3"));}
}

🍷已有的缓存工具

        缓存又分为本地缓存和分布式缓存,这里主要看本地缓存

        当你还在造轮子的时候,何不抬头看看,眼前已经停了一堆法拉犁了

        来看看都有哪些好用的工具

        🍧 1. 谷拉利 -----  基于 Guava Cache 实现本地缓存 (稍次之)   

  • 支持最大容量限制

  • 支持两种过期删除策略(插入时间和读取时间)

  • 支持简单的统计功能

  • 基于 LRU 算法实现

        🍫 2. 咖拉利 ---- 基于 Caffeine 实现本地缓存 (推荐使用)

        可以看作是 Guava Cache 的增强版,功能上两者类似,不同的是 Caffeine 采用了一种结合 LRU、LFU 优点的算法:W-TinyLFU,在性能上有明显的优越性。

        

        🍬 3. En拉利 ----  基于 Encache 实现本地缓存  (了解)

  • 支持多种缓存淘汰算法,包括 LRU、LFU 和 FIFO

  • 缓存支持堆内存储、堆外存储、磁盘存储(支持持久化)三种

  • 支持多种集群方案,解决数据共享问题

🍹章末

         文章到这里就结束了~


http://www.ppmy.cn/embedded/19445.html

相关文章

go自编自导自写一片协成池

近段时间&#xff0c;在用go的时候找了许久没有发现go协成池之类的东西&#xff0c;然后自己脑子一热&#xff0c;手撸的一个协成池&#xff0c;希望这个东西可以帮助到&#xff0c;也在go语言中苦苦寻求go协成池的伙伴&#xff0c;有什么想法可以留言到下面 func TestGoPoll(…

【c++】探究C++中的list:精彩的接口与仿真实现解密

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章来到list有关部分&#xff0c;这一部分函数与前面的类似&#xff0c;我们简单讲解&#xff0c;重难点在模拟实现时的迭代器有关实现 目录 1.List介绍2.接…

pytest测试之conftest详解

一、概述   Conftest是一个Python测试框架&#xff0c;它是pytest的一个组件&#xff0c;用于配置测试环境和参数。通过Conftest&#xff0c;我们可以创建一个可复用的测试配置文件&#xff0c;以便在多个测试模块之间共享配置信息。Conftest非常适合用于管理大型项目中的测试…

Git泄露和hg泄露原理理解和题目实操

一.Git泄露 1.简介 Git是一个开源的分布式版本控制系统&#xff0c;它可以实现有效控制应用版本&#xff0c;但是在一旦在代码发布的时候&#xff0c;存在不规范的操作及配置&#xff0c;就很可能将源代码泄露出去。那么&#xff0c;一旦攻击者发现这个问题之后&#xff0c;就…

mybatis基本使用

文章目录 1. mybatis2. 基本使用(1) maven坐标(2) 配置文件编写(3) 数据库操作(4) 注解查询 2. 基本配置(1) 读取外部配置文件(2) mapper映射 3. 映射文件查询删除/修改/新增 动态sql 1. mybatis MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高…

力扣1518. 换水问题

题目链接 力扣1518. 换水问题 简单方法(模拟) 思路 对换水进行模拟&#xff0c;每次喝完 n u m E x c h a n g e numExchange numExchange 瓶水后就去换一瓶水&#xff0c;直到不能再兑换为止&#xff0c;也就是剩余水的数量小于 n u m E x c h a n g e numExchange numE…

公认最好的随身WiFi的格行5G随身WiFi真实测评!格行5G和纽曼5G随身WiFi哪个好?5G随身WiFi推荐第一名

随着5G信号基站的铺设逐渐完善&#xff0c;各大通讯移动公司也都适时的推出了属于自己的5G随身WiFi。其中老牌企业纽曼与格行的5G随身WiFi最受大家的欢迎。那么二者到底谁才是5G设备中的王者呢&#xff1f;今天就做一个全面测评。 一、首先是颜值党们最为关注的外观问题 纽曼5…

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(六)SwiGLU 激活函数

探索和构建 LLaMA 3 架构&#xff1a;深入探讨组件、编码和推理技术&#xff08;六&#xff09;SwiGLU 激活函数 SwiGLU 激活函数 SwiGLU 是深度神经网络中使用的激活函数&#xff0c;是 GLU&#xff08;门控线性单元&#xff09;的变体。它用于通过获取输入的加权和并对其应…