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

相关文章

PostgreSQL 默认隔离级别的设置

《PostgreSQL默认隔离级别的设置》PostgreSQL的默认事务隔离级别是读已提交,这是其事务处理系统的基础行为模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一 默认隔离级别概述1.1 默认设置1.2 各版本一致性二 读已提交的特性2.1 行为特征2.2

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

mtu设置多少网速最快? 路由器MTU设置最佳网速的技巧

《mtu设置多少网速最快?路由器MTU设置最佳网速的技巧》mtu设置多少网速最快?想要通过设置路由器mtu获得最佳网速,该怎么设置呢?下面我们就来看看路由器MTU设置最佳网速的技巧... 答:1500 MTU值指的是在网络传输中数据包的最大值,合理的设置MTU 值可以让网络更快!mtu设置可以优化不同的网

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET