Caffeine 本地高速缓存工具类
目录
Caffeine工具类方式
SpringBoot 整合 Caffeine 缓存 (SpringCache模式)
驱逐策略
开发使用
Caffeine是一种高性能的缓存库,是基于Java 8的最佳(最优)缓存框架,性能各方面优于guava。
Caffeine工具类方式
原文链接:https://www.cnblogs.com/wudiffs/p/11585757.html
代码仓库如下:
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.4.0</version>
</dependency>
代码详细示例如下:
public class CaffeineCacheManagerService {private static LoadingCache<String, CacheVO> cache;private static AsyncLoadingCache<String, CacheVO> asyncCache;private static AsyncLoadingCache<String, CacheVO> asyncCache1;private static ExecutorService executorService = new ThreadPoolExecutor(8, 8, 8, TimeUnit.SECONDS, newLinkedBlockingQueue<Runnable>(1204));static {cache = Caffeine.newBuilder()// 初始化缓存长度.initialCapacity(1024 * 10)// 最大长度.maximumSize(1024 * 10)// 更新策略.refreshAfterWrite(10, TimeUnit.SECONDS)// 设置缓存的过期时间.expireAfterWrite(10, TimeUnit.SECONDS).build(new CacheLoader<String, CacheVO>() {// 同步加载@CheckForNull@Overridepublic CacheVO load(@Nonnull String key) throws Exception {return createCacheVO(key);}// getAll将会对缓存中没有值的key分别调用CacheLoader.load方法来构建缓存的值。// 我们可以重写CacheLoader.loadAll方法来提高getAll的效率。@Nonnull@Overridepublic Map<String, CacheVO> loadAll(@Nonnull Iterable<? extends String> keys) throws Exception {return createBatchCacheVOs(keys);}});// 异步加载 同步load写法,最后也会转异步asyncCache = Caffeine.newBuilder().maximumSize(1024 * 10).expireAfterWrite(10, TimeUnit.SECONDS).buildAsync(new CacheLoader<String, CacheVO>() {@CheckForNull@Overridepublic CacheVO load(@Nonnull String key) throws Exception {return createCacheVO(key);}@Nonnull@Overridepublic Map<String, CacheVO> loadAll(@Nonnull Iterable<? extends String> keys) {return createBatchCacheVOs(keys);}});// 异步加载 异步load写法asyncCache1 = Caffeine.newBuilder().maximumSize(1024 * 10).expireAfterWrite(10, TimeUnit.SECONDS).buildAsync(new AsyncCacheLoader<String, CacheVO>() {@Nonnull@Overridepublic CompletableFuture<CacheVO> asyncLoad(@Nonnull String key, @Nonnull Executor executor) {return asyncCreateCacheVO(key, executor);}@Nonnull@Overridepublic CompletableFuture<Map<String, CacheVO>> asyncLoadAll(@Nonnull Iterable<? extends String> keys, @Nonnull Executor executor) {return asyncCreateBatchCacheVOs(keys, executor);}});}public static CompletableFuture<CacheVO> asyncCreateCacheVO(String key, Executor executor) {return CompletableFuture.supplyAsync(() -> createCacheVO(key), executor);}public static CompletableFuture<Map<String, CacheVO>> asyncCreateBatchCacheVOs(Iterable<? extends String> keys, Executor executor) {return CompletableFuture.supplyAsync(() -> createBatchCacheVOs(keys), executor);}public static CacheVO createCacheVO(String key) {return new CacheVO(key);}public static Map<String, CacheVO> createBatchCacheVOs(Iterable<? extends String> keys) {Map<String, CacheVO> result = new HashMap<>();for (String key : keys) {result.put(key, new CacheVO(key));}return result;}public static void main(String[] args) throws Exception {CacheVO cacheVO1 = cache.get("AA");List<String> list = new ArrayList<>();list.add("BB");list.add("CC");Map<String, CacheVO> map = cache.getAll(list);// 如果有缓存则返回;否则运算、缓存、然后返回,整个过程是阻塞的// 即使多个线程同时请求该值也只会调用一次Function方法CacheVO cacheVO2 = cache.get("DD", (k) -> createCacheVO(k));System.out.println(JSON.toJSONString(cacheVO2));// 单个清除cache.invalidate("AA");// 批量清除cache.invalidateAll(list);// 全部清除cache.invalidateAll();// 返回一个CompletableFutureCompletableFuture<CacheVO> future = asyncCache.get("EE");CacheVO asyncCacheVO = future.get();System.out.println(JSON.toJSONString(asyncCacheVO));// 返回一个CompletableFuture<MAP<>>CompletableFuture<Map<String, CacheVO>> allFuture = asyncCache.getAll(list);Map<String, CacheVO> asyncMap = allFuture.get();System.out.println(JSON.toJSONString(asyncMap));CompletableFuture<CacheVO> future1 = asyncCache1.get("FF");CacheVO asyncCacheVO1 = future1.get();System.out.println(JSON.toJSONString(asyncCacheVO1));CompletableFuture<Map<String, CacheVO>> allFuture1 = asyncCache1.getAll(list);Map<String, CacheVO> asyncMap1 = allFuture.get();System.out.println(JSON.toJSONString(asyncMap1));}}
或者使用下发方式实现Caffeine 工具类
支持同步、异步读写缓存实现
import com.github.benmanes.caffeine.cache.AsyncCache;
import com.github.benmanes.caffeine.cache.Caffeine;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;public class CaffeineCacheUtils {private static com.github.benmanes.caffeine.cache.Cache<Object, Object> syncCache;private static AsyncCache<Object, Object> asyncCache;private CaffeineCacheUtils() {}public static void initCache() {syncCache = Caffeine.newBuilder().initialCapacity(100).maximumSize(1000).expireAfterWrite(30, TimeUnit.MINUTES).build();asyncCache = Caffeine.newBuilder().initialCapacity(100).maximumSize(1000).expireAfterWrite(30, TimeUnit.MINUTES).buildAsync();}public static void putSync(Object key, Object value) {syncCache.put(key, value);}public static Object getSync(Object key) {return syncCache.getIfPresent(key);}public static CompletableFuture<Object> getAsync(Object key, Executor executor) {return asyncCache.get(key, k -> CompletableFuture.supplyAsync(() -> fetchDataFromDataSource(k), executor));}public static CompletableFuture<Void> putAsync(Object key, Object value, Executor executor) {return asyncCache.put(key, CompletableFuture.completedFuture(value), executor);}public static void removeSync(Object key) {syncCache.invalidate(key);}public static void clearSync() {syncCache.invalidateAll();}private static Object fetchDataFromDataSource(Object key) {// 模拟从数据源获取数据的操作// 这里可以根据具体业务需求进行实现return null;}
}
SpringBoot 整合 Caffeine 缓存 (SpringCache模式)
原文链接:https://blog.csdn.net/Listening_Wind/article/details/110085228
添加依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.6.2</version>
</dependency>
缓存配置:
如果使用了多个cahce,比如redis、caffeine等,必须指定某一个CacheManage为@primary
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.assertj.core.util.Lists;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;/*** @Author: Wxy* @Date: 2020/11/7 16:56* @Description*/
@Configuration
@EnableCaching // 开启缓存,否则无效
public class CaffeineConfig {/*** 创建基于Caffeine的Cache Manager** @return*/@Bean@Primarypublic CacheManager caffeineCacheManager() {SimpleCacheManager cacheManager = new SimpleCacheManager();ArrayList<CaffeineCache> caches = Lists.newArrayList();Map<String, Object> map = getCacheType();for (String name : map.keySet()) {caches.add(new CaffeineCache(name, (Cache<Object, Object>) map.get(name)));}cacheManager.setCaches(caches);return cacheManager;}/*** 初始化自定义缓存策略** @return*/private static Map<String, Object> getCacheType() {Map<String, Object> map = new ConcurrentHashMap<>();map.put("name1", Caffeine.newBuilder().recordStats().expireAfterWrite(10, TimeUnit.SECONDS).maximumSize(100).build());map.put("name2", Caffeine.newBuilder().recordStats().expireAfterWrite(50, TimeUnit.SECONDS).maximumSize(50).build());return map;}
}
驱逐策略
基于大小的回收策略有两种方式:基于缓存大小,基于权重,基于时间。
maximumSize : 根据缓存的计数进行驱逐 同一缓存策略 缓存的数据量,以访问先后顺序,以最大100为例,超出100驱逐最晚访问的数据缓存。
maximumWeight : 根据缓存的权重来进行驱逐(权重只是用于确定缓存大小,不会用于决定该缓存是否被驱逐)。
maximumWeight与maximumSize不可以同时使用。
Caffeine提供了三种定时驱逐策略:
expireAfterAccess(long, TimeUnit):在最后一次访问或者写入后开始计时,在指定的时间后过期。假如一直有请求访问该key,那么这个缓存将一直不会过期。
expireAfterWrite(long, TimeUnit): 在最后一次写入缓存后开始计时,在指定的时间后过期。
expireAfter(Expiry): 自定义策略,过期时间由Expiry实现独自计算。
缓存的删除策略使用的是惰性删除和定时删除。这两个删除策略的时间复杂度都是O(1)
开发使用
主要基于Spring缓存注解@Cacheable、@CacheEvict、@CachePut的方式使用
- @Cacheable :改注解修饰的方法,若不存在缓存,则执行方法并将结果写入缓存;若存在缓存,则不执行方法,直接返回缓存结果。
- @CachePut :执行方法,更新缓存;该注解下的方法始终会被执行。
- @CacheEvict :删除缓存
- @Caching 将多个缓存组合在一个方法上(该注解可以允许一个方法同时设置多个注解)
- @CacheConfig 在类级别设置一些缓存相关的共同配置(与其它缓存配合使用)
注意 :@Cacheable 默认使用标@primary 注释的CacheManage
/*** 先查缓存,如果查不到,执行方法体并将结果写入缓存,若查到,不执行方法体,直接返回缓存结果* @param id*/
@Cacheable(value = "name1", key = "#id", sync = true)
public void getUser(long id){//TODO 查找数据库
}/*** 更新缓存,每次都会执行方法体* @param user*/
@CachePut(value = "name1", key = "#user.id")
public void saveUser(User user){//todo 保存数据库
}/*** 删除* @param user*/
@CacheEvict(value = "name1",key = "#user.id")
public void delUser(User user){//todo 保存数据库
}
参考博客:https://www.cnblogs.com/wudiffs/p/11585757.html
(23条消息) SpringBoot 集成 Caffeine(咖啡因)最优秀的本地缓存_springboot caffeine_Listening_Wind的博客-CSDN博客
https://blog.csdn.net/Listening_Wind/article/details/110085228
相关文章:
Caffeine 本地高速缓存工具类
目录 Caffeine工具类方式 SpringBoot 整合 Caffeine 缓存 (SpringCache模式) 驱逐策略 开发使用 Caffeine是一种高性能的缓存库,是基于Java 8的最佳(最优)缓存框架,性能各方面优于guava。 Caffeine工具…...
加密解密软件VMProtect教程(八)许可制度之序列号生成器
VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic(本机)、Virtual Pascal和XCode编译器。 同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起…...
单源最短路的建图
1.热浪 信息学奥赛一本通(C版)在线评测系统 (ssoier.cn)http://ybt.ssoier.cn:8088/problem_show.php?pid1379 很裸的单源最短路问题,n2500,可以用dijksta或者spfa都能过,下面展示spfa的做法 #include<bits/stdc.h> usi…...
MyBatis基本操作及SpringBoot单元测试
目录 一、什么是单元测试? 1.1 单元测试的好处 1.2 单元测试的实现步骤 1.2.1 生成单元测试类: 1.2.2 SpringBootTest注解 1.2.3 检验方法结果: 二、利用MyBatis实现查询操作 2.1单表查询 2.2 参数占位符 #{} 和 ${} 2.2.1 ${} 字符…...
Linux之创建进程、查看进程、进程的状态以及进程的优先级
文章目录 前言一、初识fork1.演示2.介绍3.将子进程与父进程执行的任务分离4.多进程并行 二、进程的状态1.进程的状态都有哪些?2.查看进程的状态2.运行(R)3.阻塞4.僵尸进程(Z)1.僵尸状态概念2.为什么要有僵尸状态&#…...
k8s部署rabbitmq
docker pull rabbitmq:3.9.28-management 1.部署模板 apiVersion: v1 kind: Service metadata:name: rabbitmq spec:ports:- name: amqpport: 5672targetPort: 5672- name: managementport: 15672targetPort: 15672selector:app: rabbitmq---apiVersion: apps/v1 kind: Statef…...
关于QGroundControl的软件架构的理解
首先QGC是基于QT平台开发,个人理解软件架构即为项目前后端结构,以及前后端数据交互的逻辑。下面是对QGroundControl源码的一些个人理解,写这个博客只是为了记录下来,防止时间久了忘记,过程中看了一些大佬的博客来帮助理…...
Android 文本识别:MLKIT + PreviewView
随着移动设备的普及和摄像头的高像素化,利用相机进行文本识别成为了一种流行的方式。MLKit 是 Google 提供的一款机器学习工具包,其中包含了丰富的图像和语言处理功能,包括文本识别。PreviewView 是 Android Jetpack 的一部分,它提…...
刮泥机的分类有哪些及组成部分
刮泥机的分类有哪些及组成部分 刮泥机的分类: 刮泥机主要包括:周边传动刮泥机、中心传动浓缩刮泥机。 1、中心传动浓缩刮泥机:主要由溢流装置、大梁及拦杆、进口管、传动装置、电器箱、稳流筒、主轴、浮渣耙板、刮集装置、水下轴承、小刮刀、…...
Qt编程基础 | 第六章-窗体 | 6.2、VS导入资源文件
一、VS导入资源文件 1.1、导入资源文件 步骤一: 将所有图片放到各自文件夹下,并将文件夹拷贝到资源文件(.qrc文件)的同级目录下,如下: 步骤二: 新建VS项目的时候,系统会自动建好一…...
NET框架程序设计-第4章类型基础
4.1 所有类型的基类型:System.Object CLR 要求每个类型最终都要继承自 System.Object 类型。 两种类型定义: 1)隐式继承 //隐式继承 Object class Employee{}2)显式继承 class Employee:System.Object{}System.Object 主要的公…...
Java设计模式-备忘录模式
简介 在软件开发中,设计模式是为了解决常见问题而提出的一种经过验证的解决方案。备忘录模式(Memento Pattern)是一种行为型设计模式,它允许我们在不破坏封装性的前提下,捕获和恢复对象的内部状态。 备忘录模式是一种…...
Zookeeper集群 + Kafka集群
Zookeeper 概述 Zookeeper 定义 Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数…...
“邮件营销新趋势,这个平台让你收获颇丰!
随着各媒体平台的迅速发展,2023年大家更专注于视频营销、网红营销、直播营销等营销方式。可以见得,数字媒介手段的发展,对于营销方式也产生了巨大的影响。但是,企业在拥抱新兴的营销方式的同时,也不要忽视传统的营销方…...
Python列表推导
列表推导式 列表推导式创建列表的方式更简洁。常见的用法为,对序列或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。 例如,创建平方值的列表: squares [] for …...
git使用查看分支、创建分支、合并分支
一、查看分支 查看的git命令如下: git branch 列出本地已经存在的分支,并且当前分支会用*标记 git branch -r 查看远程版本库的分支列表 git branch -a 查看所有分支列表(包括本地和远程,remotes/开头的表示远程分支)…...
vue3.0与vue2.0
一、生命周期的变化 1.vue2.响应式架构 2.vue3.0 响应式架构图 Vue3.0响应式框架在设计上,将视图渲染和数据响应式完全分离开来。将响应式核心方法effect从原有的Watcher中抽离。这样,当我们只需要监听数据响应某种逻辑回调(例如监听某个text属性的变化…...
HTML 中的常用标签用法
HTML是构建Web页面的基础语言,其中包含许多不同类型的标签。这些标签由尖括号包围,以指示浏览器如何呈现文本。下面是HTML中的一些常用标签以及它们的使用方法: 标题标签(h1-h6) 标题标签用于标识页面内容的标题&…...
【C++】指针 - 定义和使用,所占内存空间,空指针,野指针,const 修饰指针,指针和数组,指针和函数
文章目录 1. 定义和使用2. 所占内存空间3. 空指针4. 野指针5. const 修饰指针6. 指针和数组7. 指针和函数 1. 定义和使用 数据类型 * 变量名; 指针的作用是,可以通过指针间接访问内存。 内存编号是从 0 开始记录的,一般用十六进制数字表示。可以利用指…...
新规之下产业园区如何合理收费水电费用
一、政策背景 2018年3月30日,国家发改委发布《国家发展改革委关于降低一般工商业电价有关事项的通知》。明确提出进一步规范和降低电网环节收费,一是提高两部制电价的灵活性;二是全面清理规范电网企业在输配电价之外的收费项目,重…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
