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

相关文章

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

PyCharm如何设置新建文件默认为LF换行符

《PyCharm如何设置新建文件默认为LF换行符》:本文主要介绍PyCharm如何设置新建文件默认为LF换行符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm设置新建文件默认为LF换行符设置换行符修改换行符总结PyCharm设置新建文件默认为LF

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息