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

news2024/11/18 13:56:40

目录

🍸前言

🍻手写缓存服务

        (1)缓存实体类

        (2)缓存工具类

        (3)测试缓存服务

🍷已有的缓存工具

🍹章末


🍸前言

        俗话说 有轮子不用 就是玩

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

🍻手写缓存服务

        (1)缓存实体类

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

import lombok.Data;

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

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

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 秒,第三个数据不设置过期时间,也就是永不过期,然后分多次时间查询,结果如下:

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.coloradmin.cn/o/1629772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【kettle003】kettle访问SQL Server数据库并处理数据至execl文件

一直以来想写下基于kettle的系列文章&#xff0c;作为较火的数据ETL工具&#xff0c;也是日常项目开发中常用的一款工具&#xff0c;最近刚好挤时间梳理、总结下这块儿的知识体系。 熟悉、梳理、总结下Microsoft SQL Server 2022关系数据库相关知识体系 kettle访问SQL Server数…

关于远程桌面端口的优化措施的建议

在信息技术的世界中&#xff0c;远程桌面连接已成为企业、教育和个人用户之间共享信息、协作工作的重要工具。而这一切的背后&#xff0c;都离不开远程桌面端口&#xff08;RDP&#xff0c;Remote Desktop Protocol Port&#xff09;的支持。RDP端口不仅关乎到远程访问的顺畅性…

永磁同步电机SMO负载转矩观测matlab模型。

永磁同步电机SMO负载转矩观测matlab模型。 负载转矩的有效识别是提高伺服驱动系统抗负载扰动性能的关键之一。现在的传统结构的LTID滑模观测器存在频率抖动大&#xff0c;估计精度差的缺点&#xff0c;限制了其在高性能伺服系统中的应用。 本模型推导分析了传统LTID滑模观测器…

LLM大语言模型(十三):ChatGLM3-6B兼容Langchain的Function Call的一步一步的详细转换过程记录

# LangChain&#xff1a;原始prompt System: Respond to the human as helpfully and accurately as possible. You have access to the following tools: Calculator: Useful for when you need to calculate math problems, args: {\calculation\: {\description\: \calcul…

【软件安装】(十六)双系统Ubuntu22.04引导启动菜单的默认项

一个愿意伫立在巨人肩膀上的农民...... 好学的人总是喜欢在电脑上安装双系统&#xff0c;可是安装好系统之后&#xff0c;就会出现默认启动优先级的苦恼&#xff0c;如果在Bios中设置Windows引导启动为优先启动&#xff0c;那么每次想要进如Ubuntu系统就都需要重新设置Bios。如…

ubuntu的镜像源+bionic版本

首先第一步 查找和你自己ubuntu版本匹配的版本号 匹配代号如下 在终端输入lsb_release -a查看自己系统上的版本号 可以看到我这个版本号的代号是bionic。 每个版本的镜像文件都是有规律的。 bionic版本的源如下 # 阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic ma…

舌头分割YOLOV8-SEG

舌头分割&#xff0c;基于YOLOV8-SEG&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;从而摆脱YOLO依赖&#xff0c;支持C,PYTHON,ANDROID开发 舌头分割YOLOV8-SEG

【小沐学Java】VSCode搭建Java开发环境

文章目录 1、简介2、安装VSCode2.1 简介2.2 安装 3、安装Java SDK3.1 简介3.2 安装3.3 配置 4、安装插件Java Extension Pack4.1 简介4.2 安装4.3 配置 结语 1、简介 2、安装VSCode 2.1 简介 Visual Studio Code 是一个轻量级但功能强大的源代码编辑器&#xff0c;可在桌面上…

记录些 LLM 常见的问题和解析

1、提示校准为什么有助于减轻基于提示的学习中的偏见? 提示校准包括调整提示&#xff0c;尽量减少产生的输出中的偏差。 其他&#xff1a;微调修改模型本身&#xff0c;而数据增强扩展训练数据&#xff0c;梯度裁剪防止在训练期间爆炸梯度。 2、是否需要为所有基于文本的LL…

优化大型语言模型交互:提升查询和提示效果的26条原则

推荐下arxiv挂的一个提示词教程&#xff1a; https://github.com/VILA-Lab/ATLAS https://arxiv.org/abs/2312.16171 它提出了一套26条指导原则&#xff0c;改善和优化与大型语言模型&#xff08;LLMs&#xff09;的交互过程。通过这些原则&#xff0c;旨在简化对LLMs的查询和…

LabVIEW飞机机电系统综合测试平台

LabVIEW飞机机电系统综合测试平台 在现代航空领域&#xff0c;机电系统的准确性与可靠性对飞行安全至关重要。针对飞机机电管理计算机&#xff08;UMC&#xff09;复杂度增加、测试覆盖率低、效率不高等问题&#xff0c;开发了一套基于LabVIEW的机电系统综合测试平台。平台通过…

LAMP(Linux+Apache+MySQL+PHP)环境介绍、配置、搭建

LAMP(LinuxApacheMySQLPHP)环境介绍、配置、搭建 LAMP介绍 LAMP是由Linux&#xff0c; Apache&#xff0c; MySQL&#xff0c; PHP组成的&#xff0c;即把Apache、MySQL以及PHP安装在Linux系统上&#xff0c;组成一个环境来运行PHP的脚本语言。Apache是最常用的Web服务软件&a…

jupyter notebook设置代码自动补全

jupyter notebook设置代码自动补全 Anaconda Prompt窗口执行 pip install jupyter_contrib_nbextensionsjupyter contrib nbextensions install --userpip install jupyter_nbextensions_configuratorjupyter nbextensions_configurator enable --user按如下图片设置 卸载jed…

(bevfusion:多模态融合)报错:AttributeError: module ‘numpy‘ has no attribute ‘long‘

解决办法1&#xff1a;降低numpy版本&#xff08;我的报错版本是1.24.4&#xff09; pip install numpy1.20.3解决办法2&#xff1a;或者将np.long改为np.int64 (由于我的报错在环境内部&#xff0c;不好修改&#xff0c;所以直接降低的numpy版本)

2024年3月电子学会Python等级考试试卷(三级)真题,包含答案

202403Python 三级真题 1、在Python中,hex(2023)的功能是?() A.将十进制数 2023 转化为十六进制数 B.将十进制数 2023 转化为八进制数 C.将十六进制数 2023转化为十进制数 D.将八进制数 2023转化为十进制数

双重注意力模块 DoubleAttention | A2-Nets: Double Attention Networks

论文名称&#xff1a;《 A 2 A^2 A2-Nets: Double Attention Networks》 论文地址&#xff1a;https://arxiv.org/pdf/1810.11579.pdf 学习捕捉远距离关系对于图像/视频识别是基础性的。现有的CNN模型通常依靠增加深度来建模这些关系&#xff0c;这在很大程度上效率低下。在这…

C++ | Leetcode C++题解之第51题N皇后

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<string>> solveNQueens(int n) {auto solutions vector<vector<string>>();auto queens vector<int>(n, -1);auto columns unordered_set<int>();auto diag…

【MHA】MySQL高可用MHA介绍1-功能,架构,优势,案例

目录 一 MHA 介绍 1 MHA功能 自动化主服务器监控和故障转移 交互式&#xff08;手动启动的&#xff09;主故障转移 非交互式主故障转移 在线切换主机 2 主服务器故障转移的难点 二 MHA架构 1 MHA组件 2 自定义扩展&#xff08;脚本&#xff09; 三 MHA优势 1 MHA可以…

详解SPI、I2C、UART、I2S、GPIO、SDIO、CAN

总线,总线,总要陷进里面。这世界上的信号都一样,但是总线却成千上万,让人头疼。 总的来说,总线有三种:内部总线、系统总线和外部总线。内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连;而系统总线是微机中各插件板与系统板之间的总线,用于插件板一…

Hive函数详解

Hive 是一个建立在 Hadoop 上的数据仓库基础架构&#xff0c;它提供了类似于 SQL 的查询语言&#xff0c;称为 HiveQL&#xff0c;用于对存储在 Hadoop 分布式文件系统中的数据进行查询和分析。 1.函数简介 Hive会将常用的逻辑封装成函数给用户进行使用&#xff0c;类似于Jav…