一篇搞懂Caffeine

news2024/11/26 6:20:59

概念

Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。

缓存和ConcurrentMap有点相似,但还是有所区别。最根本的区别是ConcurrentMap将会持有所有加入到缓存当中的元素,直到它们被从缓存当中手动移除。但是,Caffeine的缓存Cache 通常会被配置成自动驱逐缓存中元素,以限制其内存占用。在某些场景下,LoadingCache和AsyncLoadingCache 因为其自动加载缓存的能力将会变得非常实用。

官网

Home zh CN · ben-manes/caffeine Wiki · GitHubicon-default.png?t=N7T8https://github.com/ben-manes/caffeine/wiki/Home-zh-CN

对比

功能CaffeineConcurrentMap
添加-手动加载支持支持
添加-自动加载支持不支持
添加-手动异步加载支持不支持
添加-自动异步加载支持不支持
删除支持支持
驱逐策略支持不支持

说明:Caffeine和ConcurrentMap最重要的一个区别就是在于,Caffeine可以设置过期策略,类似redis一样

操作

引包

        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
            <version>2.9.0</version>
        </dependency>

初始化

public Cache<String, Object> caffeineCache() {
        return Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(1000000)
                .build();
}

说明:

expireAfterWrite:表示在元素最后一次更新的时候,10分钟后过期

maximumSize:表示当前缓存中可以放入的最大元素的数量

添加

Caffeine提供了四种缓存添加策略:手动加载,自动加载,手动异步加载和自动异步加载。

手动加载

cache.put(key, graph);

自动加载

    /**
     * 自动加载
     */
    public static void auto(){
        LoadingCache<String, String> loadingCache = Caffeine.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .build(key -> loadValueFromDatabase(key));

        String value2 = loadingCache.get("key1");
        System.out.println("Value for key1: " + value2);
    }

    /**
     * 自定义加载方法,例如从数据库或其他数据源加载值
     * @param key
     * @return
     */
    private static String loadValueFromDatabase(String key) {
        System.out.println("Loading value for key: " + key + " from database...");
        // 这里可以添加实际加载数据的逻辑,这里只是示例直接返回一个字符串
        return "Value for " + key + " from database";
    }

异步操作

异步操作不在此说明,可以参考官网:Population zh CN · ben-manes/caffeine Wiki · GitHubicon-default.png?t=N7T8https://github.com/ben-manes/caffeine/wiki/Population-zh-CN

驱逐

Caffeine 提供了三种驱逐策略,分别是基于容量,基于时间和基于引用三种类型。

基于容量

设置maximumSize参数可以,遵循先进先出的原则

LoadingCache<String, String> loadingCache = Caffeine.newBuilder()
                .maximumSize(1)
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .build(key -> loadValueFromDatabase(key));

基于时间

设置expireAfterWrite参数,设置30秒过期

LoadingCache<String, String> loadingCache = Caffeine.newBuilder()
                .maximumSize(1)
                .expireAfterWrite(30, TimeUnit.SECONDS)
                .build(key -> loadValueFromDatabase(key));

Caffeine提供了三种方法进行基于时间的驱逐:

  • expireAfterAccess(long, TimeUnit): 一个元素在上一次读写操作后一段时间之后,在指定的时间后没有被再次访问将会被认定为过期项。在当被缓存的元素时被绑定在一个session上时,当session因为不活跃而使元素过期的情况下,这是理想的选择。
  • expireAfterWrite(long, TimeUnit): 一个元素将会在其创建或者最近一次被更新之后的一段时间后被认定为过期项。在对被缓存的元素的时效性存在要求的场景下,这是理想的选择。
  • expireAfter(Expiry): 一个元素将会在指定的时间后被认定为过期项。当被缓存的元素过期时间收到外部资源影响的时候,这是理想的选择。

基于引用

主要将元素设置成弱引用, 然后讲个GC去回收,详细可以看官网Eviction zh CN · ben-manes/caffeine Wiki · GitHubicon-default.png?t=N7T8https://github.com/ben-manes/caffeine/wiki/Eviction-zh-CN

策略(过期时间) 

Caffeine没有直接提供设置不同过期时间的方法,但是提供了策略

cache.policy().expireAfterAccess().ifPresent(expiration -> ...);
cache.policy().expireAfterWrite().ifPresent(expiration -> ...);
cache.policy().expireVariably().ifPresent(expiration -> ...);
cache.policy().refreshAfterWrite().ifPresent(refresh -> ...);

实例

1、定义过期时间策略

package com.lyc.caffeine.config;

import com.github.benmanes.caffeine.cache.Expiry;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * @Projectname: caffeine
 * @Filename: CaffeineExpiry
 * @Author: lyc
 * @Data:2023/11/23 10:06
 * @Description: 自定义过期策略,实现Expiry接口
 */
public class CaffeineExpiry implements Expiry<String, Object> {

    private static Logger logger = LoggerFactory.getLogger(CaffeineExpiry.class);

    /**
     * 创建
     * @param key
     * @param value
     * @param currentTime
     * @return
     */
    @Override
    public long expireAfterCreate(@NonNull String key, @NonNull Object value, long currentTime) {
        logger.debug("创建缓存key:" + key + ",值value:" + value + ", 过期时间currentTime:" + currentTime);
        return TimeUnit.MINUTES.toNanos(5);
    }

    /**
     * 修改
     * @param key
     * @param value
     * @param currentTime
     * @param currentDuration
     * @return
     */
    @Override
    public long expireAfterUpdate(@NonNull String key, @NonNull Object value, long currentTime, @NonNegative long currentDuration) {
        logger.debug("更新缓存key:" + key + ",值value:" + value + ", 过期时间currentTime:" + currentTime + ", 持续时间currentDuration:" + currentDuration);
        return currentDuration;
    }

    /**
     * 查询
     * @param key
     * @param value
     * @param currentTime
     * @param currentDuration
     * @return
     */
    @Override
    public long expireAfterRead(@NonNull String key, @NonNull Object value, long currentTime, @NonNegative long currentDuration) {
        logger.debug("读缓存key:" + key + ",值value:" + value + ", 过期时间currentTime:" + currentTime + ", 持续时间currentDuration:" + currentDuration);
        return currentDuration;
    }
}

2、初始化缓存

 public Cache<String, Object> caffeineCache() {
        return Caffeine.newBuilder()
                .expireAfter(new CaffeineExpiry())
                .initialCapacity(100)
//                .maximumSize(MAXIMUM_SIZE)
                .build();
    }

3、使用

package com.lyc.caffeine.util;

import cn.hutool.core.util.ObjectUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.lyc.caffeine.config.CaffeineConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Projectname: caffeine
 * @Filename: CaffeineCacheUtil
 * @Author: lyc
 * @Data:2023/11/23 14:51
 * @Description: 缓存工具类
 */
public class CaffeineCacheUtil {

    /**
     * 过期时长
     */
    private static long duration = 5L;

    /**
     * 时间单位
     */
    private static TimeUnit timeUnit = TimeUnit.MINUTES;

    /**
     * 缓存
     */
    public static Cache<String, Object> caffeineCache;

    

    /**
     * 添加-默认过期时间
     *
     * @param key   key
     * @param value value
     */
    public static void put(String key, Object value) {
        caffeineCache.policy().expireVariably().ifPresent(e -> {
            e.put(key, value, duration, timeUnit);
        });
    }

    
}

工具类代码资源

Caffeine工具包资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1257713.html

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

相关文章

虹科Pico汽车示波器 | 汽车免拆检修 | 2016款东风悦达起亚K5车发动机怠速抖动严重、加速无力

一、故障现象 一辆2016款东风悦达起亚K5车&#xff0c;搭载G4FJ发动机&#xff0c;累计行驶里程约为8.2万km。该车发动机怠速抖动严重、加速无力&#xff0c;同时发动机故障灯异常点亮&#xff0c;为此在其他维修厂更换了所有点火线圈和火花塞&#xff0c;故障依旧&#xff0c;…

JavaScript 的 DOM 知识点有哪些?

文档对象模型&#xff08;Document Object Model&#xff0c;简称 DOM&#xff09;&#xff0c;是一种与平台和语言无关的模型&#xff0c;用来表示 HTML 或 XML 文档。文档对象模型中定义了文档的逻辑结构&#xff0c;以及程序访问和操作文档的方式。 当网页加载时&#xff0…

Linux 项目自动化构建工具:make/makefile

什么是 make make 是一个命令&#xff0c;他会在源文件的当前目录下寻找 makefile 或者 Makefile 文件执行这个文件中的代码。 makefile 文件的编写 我们先来见见猪跑&#xff0c;看看 make 怎么用的&#xff1a; 下面是 makefile 文件的内容&#xff1a; 这是 test.c 中的…

【AD9510 概要总结】A..

目录 特征FEATURES概述 GENERAL DESCRIPTION功能描述 FUNCTIONAL DESCRIPTIONPLL部分REFIN PLL参考输入—REFINVCO/VCXO时钟输入—CLK2PLL基准分频器—RVCO/VCXO 反馈分频器—N (P, A, B)A 和 B 计数器确定 P、A、B 和 R 的值 鉴频鉴相器&#xff08;PFD&#xff09;和电荷泵消…

国联易安:“主动防御”才能保障数据库安全

随着IT与互联网技术高速发展,政府、金融、电信、教育、医疗等各行业的数据成为了组织机构的核心资产。一旦数据被泄漏,不仅会造成严重经济损失&#xff0c;而且会带来极大负面社会影响。 国联易安国联数据库安全防护系统是一款基于数据库协议分析与控制技术的数据库主动防御系统…

如何编写自己的python包,并在本地进行使用

如何编写自己的python包,并在本地进行使用 一、直接引用 1.创建Python项目pythonProject。 2.并且在此项目下创建pg_message包。 3.pg_message包下默认生成_init_.py文件。 Python中_init_.py是package的标志。init.py 文件的一个主要作用是将文件夹变为一个Python模块,Pyt…

汇编程序:查0~9的平方表获得平方数

查平方表。在数据段中建立一个表格TABLE&#xff0c;存放0~9的平方值。从键盘输入一个十进制数字(0~9)&#xff0c;查表求键入数字的平方值。并把结果显示在CRT屏幕上。能够单步执行程序&#xff0c;认真观察、判断每条指令执行的结果是否正确&#xff0c;对错误结果&#xff0…

【网络安全】-常见的网站攻击方式详解

文章目录 介绍1. SQL 注入攻击攻击原理攻击目的防范措施 2. 跨站脚本攻击&#xff08;XSS&#xff09;攻击原理攻击目的防范措施 3. CSRF 攻击攻击原理攻击目的防范措施 4. 文件上传漏洞攻击原理攻击目的防范措施 5. 点击劫持攻击原理攻击目的防范措施 结论 介绍 在数字时代&a…

工具: OPC-UA学习和模型搭建

本文采用的是open62541 V1.3.8 作为OPC-UA的开发的支持库官网 使用文档说明 git相关 git源码 Release版本 下载最新的git源码或者release版本发布包&#xff0c;之后按照使用文档进行编译可以生成动态库。推荐使用的是release发布包。open62541内部有其他的git库依赖 将动态…

微软重磅更新:Bing Chat全线改名Copilot,用户可免费使用GPT4!(文末附Copilot使用教程)

原创 | 文 BFT机器人 微软在2023年的Ignite大会上宣布了许多新产品和功能。其中最引人注目的是Bing Chat更名为Copilot&#xff0c;Copilot基于最新的OpenAI模型&#xff0c;包括GPT-4和DALL・E 3&#xff0c;为用户提供文本和图像生成功能。也就是说&#xff0c;只要你拥有微…

文件元数据批量修改:mp3音频和mp4视频的元数据如何批量修改

在数字媒体处理和管理的日常工作中&#xff0c;文件元数据的批量修改是一个常见的需求。元数据&#xff0c;或者称为文件信息&#xff0c;可以包括文件的创建日期、修改日期、文件名、文件大小、标签等。在音乐和视频处理领域&#xff0c;例如对mp3音频和mp4视频文件&#xff0…

关于铝镓氮(AlGaN)上p-GaN的高选择性、低损伤蚀刻

引言 GaN基高电子迁移率晶体管&#xff08;HEMT&#xff09;由于其高频和低导通电阻的特性&#xff0c;近来在功率开关应用中引起了广泛关注。二维电子气&#xff08;2DEG&#xff09;是由AlGaN/GaN异质结中强烈的自发和压电极化效应引起的&#xff0c;这导致传统器件通常处于…

ICMPv6报文与邻居状态跟踪

ICMPv6报文 ICMPv6(Internet Control Message Protocol for the IPv6)是IPv6的基础协议之一。 在IPv4中,Internet控制报文协议ICMP(Internet Control Message Protocol)向源节点报告关于向目的地传输IP数据包过程中的错误和信息。它为诊断、信息和管理目的定义了一些消息…

抖音本地生活服务商申请入口门槛过高,该怎么办?

近年来&#xff0c;短视频平台的举起让直播带货和本地生活服务行业逐渐兴起&#xff0c;并且以其便捷、高效的特点受到了广大用户的欢迎。很多创业者也加入了本地生活服务商的行列中&#xff0c;但有消息传出&#xff0c;抖音本地生活服务商申请入口可能会关闭&#xff0c;由于…

防雷接地电阻和接地网的区别及其应用

接地是电气工程中的一种重要的安全措施&#xff0c;它可以保护电气设备和人员免受雷击和过电压的危害&#xff0c;也可以提高电气系统的运行稳定性和可靠性。接地的基本原理是将电气设备或人体与大地连接成同一电位&#xff0c;从而消除或减小危险电压。 地凯科技接地的实现方式…

掌握你的Mac,iStat Menus带你了解mac系统状态

iStat Menus for mac是一款强大的mac系统状态监控工具&#xff0c;它能够提供实时的系统信息和性能监测&#xff0c;帮助用户全面了解和管理自己的Mac设备。无论是CPU、内存、网络、硬盘还是传感器数据&#xff0c;iStat Menus都能直观地展示&#xff0c;并且支持自定义布局和样…

组装自己的稳定扩散模型

在本文中&#xff0c;我们将利用 Hugging Face Diffusers 库的组件实现自己的稳定扩散模型&#xff0c;可以像 diffuser.diffuse() 一样简单地生成图像。 在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编…

基于AC6969的蓝牙控制RGB彩灯

程序的实现思路&#xff1a;单片机与手机app之间通过蓝牙实现通讯&#xff0c;通过点击屏幕上的对应色块然后app会把对应的RGB值发送到单片机。然后单片机会对数据进行解析然后把数字量转换为模拟量&#xff0c;然后通过PWM控制IO口输出不同的电压以此来达到控制RGB灯 RGB彩灯原…

运动蓝牙耳机哪个品牌好?什么运动耳机好用?运动蓝牙耳机推荐

​运动耳机作为现代人运动时不可或缺的装备&#xff0c;除了能够提供稳固舒适佩戴体验之外&#xff0c;还带来了高品质音质体验。我们在选择运动耳机时&#xff0c;需要考虑到它们的音质、稳定性、舒适度和耐用性等方面&#xff0c;以确保在运动中获得最佳的体验和效果。下面&a…

ubuntu下载vscode并运行程序

如有帮助点赞收藏关注&#xff01; 如需转载&#xff0c;请注明出处&#xff01; 好久没有在linux下编译c代码了&#xff0c;由于换了酷炫彩灯的电脑。又要重新安装一次喽。做个记录&#xff0c;可以帮助到有需要的人&#xff0c;接下来不要错过每一个步骤。 我们一起手把手运行…