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

目录

🍸前言

🍻手写缓存服务

        (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://xiahunao.cn/news/2981972.html

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

相关文章

Qt 菜单栏上手教程:QMenuBar QMenu QToolbar

引言 在Qt框架中&#xff0c;QMenuBar、QMenu、QToolbar和QAction都是用于构建应用程序界面中的用户交互元素。 QMenuBar 是什么&#xff1a;QMenuBar是一个用于创建横向菜单栏的类。在桌面应用程序中&#xff0c;它通常位于窗口的顶部。应用场景&#xff1a;当您需要一个包含…

vue快速入门(四十)非父子组件通信

注释很详细&#xff0c;直接上代码 上一篇 新增内容 媒介js的创建发送组件发送事件示例接收组件接收事件示例 源码 App.vue <template><div id"app"><TessFirst></TessFirst><TestSecond></TestSecond></div> </templ…

音视频直播原理解析

直播原理就是一个推流和拉取流的过程&#xff1b; 直播端将直播流推送至服务器&#xff0c;用户端发起请求从服务器拉取直播流然后解码播放 第一部分就是视频直播端的操作&#xff1a;视频采集处理后推流到流媒体服务器。 首先从前端采集设备中获得原始的音频、视频数据&…

车载系统的 加减串器应用示意

overview 车载系统上使用加减串器来实现camera&#xff0c; lcd屏等 图像数据的远距离传输&#xff0c;将原先在短距离传输视频信号的mipi csi&#xff0c;dsi 等的TX&#xff0c;RX中间&#xff0c;插入加减串器&#xff0c;实现长距离的可靠传输。 示意图如下 往往一路视频…

蓝海创意云亮相第二节南京大学苏州文化周系列活动

4月19日-22日&#xff0c;“AI苏州 XIU青春”南京大学苏州文化周系列活动在南京大学鼓楼校区隆重举行&#xff0c;蓝海创意云作为苏州高新区XR领域的佼佼者&#xff0c;携vLive虚拟直播亮相活动现场&#xff0c;为本次活动打造了一个极具科技感、想象力、技术力的虚拟直播体验点…

卡尔曼滤波器(一):卡尔曼滤波器简介

观看MATLAB技术讲座笔记&#xff0c;该技术讲座视频来自bilibili账号&#xff1a;MATLAB中国。 一、什么是卡尔曼滤波器 卡尔曼滤波器是一种优化估计算法&#xff0c;是一种设计最优状态观测器的方法&#xff0c;其功能为&#xff1a; 估算只能被间接测量的变量&#xff1b;通…

条件生成对抗网络(cGAN)在AI去衣技术中的应用探索

随着深度学习技术的飞速发展&#xff0c;生成对抗网络&#xff08;GAN&#xff09;作为其中的一个重要分支&#xff0c;在图像生成、图像修复等领域展现出了强大的能力。其中&#xff0c;条件生成对抗网络&#xff08;cGAN&#xff09;通过引入条件变量来控制生成模型的输出&am…

CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽

错误描述&#xff1a; 我设置了CountDownLatch对线程的协作做出了一些限制&#xff0c;但是我发现运行一段时间以后便发现定时任务不运行了。 具体代码&#xff1a; public void sendToCertainWeb() throws IOException, InterruptedException {List<String> urlList …

C++ 虚表起源

本文会让看不见 摸不着的虚表(Vtable),虚指针(Vptr)彻底现行 本文涉及思想: C 面向对象 封装 继承 多态 中的 多态 概念解释: 虚表指针&#xff1a; 这是指向虚表&#xff08;vtable&#xff09;的指针&#xff0c;虚表中包含了该类的所有虚函数对应的地址。 虚表&#x…

【Linux】使用Jenkins + svn + springboot自动构建jar包并自动打包在服务器上运行

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

【南京工程学院×朗汀留学】部分录取案例合集

朗汀留学 X 南京工程学院 作为深耕留学的专业资深团队&#xff0c;朗汀留学成功帮助上千名学生出国留学。 在此我们将南京工程学院的部分留学案例作以总结&#xff0c;以供新生参考。再次恭喜所有 获得理想大学offer的学生们&#xff0c;你们的努力让梦想照进现实。 学校介绍…

2024年51cto视频下载方法

这里教大家如何将自己购买的51cto视频下载到本地 首先要利用一个工具:小白51cto工具 我已经打包好了 小白51cto链接&#xff1a;https://pan.baidu.com/s/1jR1fze51XaYwqhuOtlW7Wg?pwd1234 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 教程开始 0.登录好51…

(三)Servlet教程——Tomcat安装与启动

首先打开浏览器在浏览器地址栏中输入清华大学开源软件镜像站地址&#xff0c;地址如下 https://mirrors.tuna.tsinghua.edu.cn/ 输入地址后回车会出现如下图所示的界面 在该界面找tomcat不是很好找&#xff0c;在搜索框中输入apache然后回车&#xff0c;输入apache后并回车后出…

代码随想录算法训练营第四十六天| LeetCode139.单词拆分

一、LeetCode139.单词拆分 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0139.%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86.html 状态&#xff1a;已解决 1.思路 单词明显就是物品&#xff0c;字符串s明显就是背包&#xff0c;那么问题就变成了物品能不能把背…

java:观察者模式

java&#xff1a;观察者模式 1 前言 观察者模式&#xff0c;又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;他定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所…

邂逅JavaScript逆向爬虫-------基础篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

Java | Leetcode Java题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution {public void rotate(int[][] matrix) {int n matrix.length;// 水平翻转for (int i 0; i < n / 2; i) {for (int j 0; j < n; j) {int temp matrix[i][j];matrix[i][j] matrix[n - i - 1][j];matrix[n - i - 1]…

YOLOv8 训练自己的数据集(20240423)

环境搭建请参考&#xff1a;Win10 搭建 YOLOv8 运行环境&#xff08;20240423&#xff09;-CSDN博客 环境测试请参考&#xff1a;本地运行测试 YOLOv8&#xff08;20240423&#xff09;-CSDN博客 一、使用 YOLOv8 的 coco128 数据集熟悉一下如何训练和预测 1.1、在项目根目录…

二手车交易平台搭建重点,会用到哪些三方服务?

在搭建二手车交易平台时&#xff0c;有几个重点方面需要关注&#xff0c;并且会涉及到一些第三方服务的使用。以下是关键点和可能用到的第三方服务&#xff1a; 一、二手车交易平台搭建重点 用户友好与界面设计&#xff1a;一个成功的二手车交易平台首先需要一个直观、易用且吸…

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

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