Caffeine:为每个元素动态设置过期时间

2023-10-31 22:04

本文主要是介绍Caffeine:为每个元素动态设置过期时间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Caffeine:为每个元素动态设置过期时间

Caffeine 是一个开源的 Java 缓存库,它提供了一个高效且易于使用的缓存解决方案,可以帮助 Java 开发人员快速实现缓存功能,提升应用程序的性能和响应速度。Caffeine 支持多种缓存策略,并具有高性能、低延迟和低内存占用的特点,是 Java 开发人员在构建高性能应用程序时不可或缺的工具之一。

对于Caffeine的缓存过期设置来说,我们知道有

  • expireAfterWrite:基于创建时间进行过期处理

  • expireAfterAccess:基于最后访问时间进行过期处理

  • expireAfter:基于个性化定制的逻辑来实现过期处理(可以定制基于新增、读取、更新等场景的过期策略,甚至支持为不同记录指定不同过期时间)

在Caffeine缓存创建时,可以使用expireAfterWriteexpireAfterAccess来设置缓存元素的过期时间,但这种过期时间的设置是基于整个缓存的所有元素来说的,即每个元素的过期时间都是这个指定的时间。

那么如果我们想针对缓存中的每个元素单独设置缓存过期时间要怎么做呢?就要涉及到expireAfter这个设置。

expireAfter方法接收一个Expiry对象来计算缓存项何时过期。在Expiry对象中需要实现expireAfterCreateexpireAfterUpdateexpireAfterRead三个方法。

  • expireAfterCreate: 指定一旦条目创建后的持续时间过了,就应该自动从缓存中删除该条目。为了表示没有过期,可以给一个条目一个过长的周期,比如Long.MAX_VALUE。
  • expireAfterUpdate: 指定在更新其值后的持续时间一过,就应自动从缓存中删除该条目。为了表示没有过期,可以给一个条目一个过长的周期,比如Long.MAX_VALUE。可以返回currentDuration来不修改过期时间。
  • expireAfterRead: 指定超过最后一次读取后的持续时间,就应自动从缓存中删除该条目。为了表示没有过期,可以给条目一个过长的周期,比如Long.MAX_VALUE。可以返回currentDuration来不修改过期时间。

话不多说,给出代码示例,大家就知道如何来写了

Example

Employee.java

public class Employee {private int id;private String firstName;private String lastName;private long expiryTime;public Employee(int id, String firstName, String lastName, long expiryTime) {super();this.id = id;this.firstName = firstName;this.lastName = lastName;this.expiryTime = expiryTime;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public long getExpiryTime() {return expiryTime;}public void setExpiryTime(long expiryTime) {this.expiryTime = expiryTime;}@Overridepublic String toString() {return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", expiryTime="+ expiryTime + "]";}}

CaffeineTest.java

public class CaffeineTest {private static void printCache(Cache cache) {System.out.println("Elements in the cache are");Map map = cache.asMap();for (Object key : map.keySet()) {System.out.println(map.get(key));}}public static void main(String args[]) throws InterruptedException {Cache<Integer, Employee> cache = Caffeine.newBuilder().expireAfter(new Expiry<Integer, Employee>() {@Overridepublic long expireAfterCreate(Integer key, Employee emp, long currentTime) {return TimeUnit.SECONDS.toNanos(emp.getExpiryTime());}@Overridepublic long expireAfterUpdate(Integer key, Employee emp, long currentTime, long currentDuration) {return currentDuration;}@Overridepublic long expireAfterRead(Integer key, Employee emp, long currentTime, long currentDuration) {return currentDuration;}}).build();Employee emp1 = new Employee(1, "Krishna", "Gurram", 5l);Employee emp2 = new Employee(2, "Gopi", "Battu", 8l);Employee emp3 = new Employee(3, "Saurav", "Sarkar", 15l);cache.put(emp1.getId(), emp1);cache.put(emp2.getId(), emp2);cache.put(emp3.getId(), emp3);printCache(cache);System.out.println("\nAbout to sleep for 6 seconds");TimeUnit.SECONDS.sleep(6);printCache(cache);System.out.println("\nAbout to sleep for 10 seconds");TimeUnit.SECONDS.sleep(4);/** Since cache eviction is done asynchronously, let's execute pending* maintenance operations needed by the cache*/
//        System.out.println("\nPerforming cleanup operations\n");
//        cache.cleanUp();printCache(cache);}
}    

Output

Elements in the cache are
Employee [id=1, firstName=Krishna, lastName=Gurram, expiryTime=5]
Employee [id=2, firstName=Gopi, lastName=Battu, expiryTime=8]
Employee [id=3, firstName=Saurav, lastName=Sarkar, expiryTime=15]About to sleep for 6 seconds
Elements in the cache are
Employee [id=2, firstName=Gopi, lastName=Battu, expiryTime=8]
Employee [id=3, firstName=Saurav, lastName=Sarkar, expiryTime=15]About to sleep for 10 seconds
Elements in the cache are
Employee [id=3, firstName=Saurav, lastName=Sarkar, expiryTime=15]

上面的代码在创建Caffeine缓存对象时,调用expireAfter来自定义缓存的过期策略。在实现expireAfterCreate方法中,根据缓存元素中设置的过期时间,来单独为每个缓存元素动态设置过期时间。

根据打印的输出可以可以验证,当程序休眠6秒后,由于id=1的元素值的过期时间是5s,所以它先过期被从缓存中删除。当程序再次休眠4s后,此时id=2的元素值也超过了设置的缓存时间,因此也被从缓存中删除。此时,缓存中只存在一个id=3的唯一一个元素。

这篇关于Caffeine:为每个元素动态设置过期时间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/318436

相关文章

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

对postgresql日期和时间的比较

《对postgresql日期和时间的比较》文章介绍了在数据库中处理日期和时间类型时的一些注意事项,包括如何将字符串转换为日期或时间类型,以及在比较时自动转换的情况,作者建议在使用数据库时,根据具体情况... 目录PostgreSQL日期和时间比较DB里保存到时分秒,需要和年月日比较db里存储date或者ti

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Spring MVC如何设置响应

《SpringMVC如何设置响应》本文介绍了如何在Spring框架中设置响应,并通过不同的注解返回静态页面、HTML片段和JSON数据,此外,还讲解了如何设置响应的状态码和Header... 目录1. 返回静态页面1.1 Spring 默认扫描路径1.2 @RestController2. 返回 html2

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情