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

相关文章

springboot+redis实现订单过期(超时取消)功能的方法详解

《springboot+redis实现订单过期(超时取消)功能的方法详解》在SpringBoot中使用Redis实现订单过期(超时取消)功能,有多种成熟方案,本文为大家整理了几个详细方法,文中的示例代... 目录一、Redis键过期回调方案(推荐)1. 配置Redis监听器2. 监听键过期事件3. Redi

JAVA Calendar设置上个月时,日期不存在或错误提示问题及解决

《JAVACalendar设置上个月时,日期不存在或错误提示问题及解决》在使用Java的Calendar类设置上个月的日期时,如果遇到不存在的日期(如4月31日),默认会自动调整到下个月的相应日期(... 目录Java Calendar设置上个月时,日期不存在或错误提示java进行日期计算时如果出现不存在的

Java利用Spire.XLS for Java自动化设置Excel的文档属性

《Java利用Spire.XLSforJava自动化设置Excel的文档属性》一个专业的Excel文件,其文档属性往往能大大提升文件的可管理性和可检索性,下面我们就来看看Java如何使用Spire... 目录Spire.XLS for Java 库介绍与安装Java 设置内置的 Excel 文档属性Java

idea设置快捷键风格方式

《idea设置快捷键风格方式》在IntelliJIDEA中设置快捷键风格,打开IDEA,进入设置页面,选择Keymap,从Keymaps下拉列表中选择或复制想要的快捷键风格,点击Apply和OK即可使... 目录idea设www.chinasem.cn置快捷键风格按照以下步骤进行总结idea设置快捷键pyth

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

MyBatis配置文件中最常用的设置

《MyBatis配置文件中最常用的设置》文章主要介绍了MyBatis配置的优化方法,包括引用外部的properties配置文件、配置外置以实现环境解耦、配置文件中最常用的6个核心设置以及三种常用的Ma... 目录MyBATis配置优化mybatis的配置中引用外部的propertis配置文件⚠️ 注意事项X

MyBatis-Plus使用动态表名分表查询的实现

《MyBatis-Plus使用动态表名分表查询的实现》本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录1. 引入依赖2. myBATis-plus配置3. TenantContext 类:租户上下文

Java中的随机数生成案例从范围字符串到动态区间应用

《Java中的随机数生成案例从范围字符串到动态区间应用》本文介绍了在Java中生成随机数的多种方法,并通过两个案例解析如何根据业务需求生成特定范围的随机数,本文通过两个实际案例详细介绍如何在java中... 目录Java中的随机数生成:从范围字符串到动态区间应用引言目录1. Java中的随机数生成基础基本随

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

C#借助Spire.XLS for .NET实现Excel工作表自动化样式设置

《C#借助Spire.XLSfor.NET实现Excel工作表自动化样式设置》作为C#开发者,我们经常需要处理Excel文件,本文将深入探讨如何利用C#代码,借助强大的Spire.XLSfor.N... 目录为什么需要自动化工作表样式使用 Spire.XLS for .NET 实现工作表整体样式设置样式配置