caffeine的基本使用

Caffeine是一款基于JDK1.8的高性能缓存库,提供过期策略和装载策略。常见用法包括设置过期时间和最大容量,以及使用removalListener监听清理事件。填充策略包括手动、自动、异步手动和异步自动加载。驱逐策略可以基于容量大小或时间,例如写入后10秒过期或写入/访问后无操作10秒过期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

java内存类库caffeine

caffeine是基于jdk1.8上开发的高性能缓存管理类库(程序内存), 它和 ConcurrentMap类似,但是增加了过期策略、装载策略等独有的东西。

     此文章转载自:https://www.kancloud.cn/ichenpeng/blog/1094838

1. 常见用法

public static void main(String... args) throws Exception {
Cache<String, String> cache = Caffeine.newBuilder()
        //5秒没有读写自动删除
        .expireAfterAccess(5, TimeUnit.SECONDS)
        //最大容量1024个,超过会自动清理空间
        .maximumSize(1024)
        .removalListener(((key, value, cause) -> {
            //清理通知 key,value ==> 键值对   cause ==> 清理原因
        }))
        .build();

//添加值
cache.put("张三", "浙江");
//获取值
cache.getIfPresent("张三");
//remove
cache.invalidate("张三");
}

2. 填充策略

填充策略是指如何在key不存在的情况下,如何创建一个对象进行返回,主要分为下面四种

2.1 手动(Manual)

public static void main(String... args) throws Exception {
        Cache<String, Integer> cache = Caffeine.newBuilder().build();

        Integer age1 = cache.getIfPresent("张三");
        System.out.println(age1);

        //当key不存在时,会立即创建出对象来返回,age2不会为空
        Integer age2 = cache.get("张三", k -> {
            System.out.println("k:" + k);
            return 18;
        });
        System.out.println(age2);
}
null
k:张三
18

2.2 自动(Loading)

public static void main(String... args) throws Exception {

    //此时的类型是 LoadingCache 不是 Cache
    LoadingCache<String, Integer> cache = Caffeine.newBuilder().build(key -> {
        System.out.println("自动填充:" + key);
        return 18;
    });

    Integer age1 = cache.getIfPresent("张三");
    System.out.println(age1);

    // key 不存在时 会根据给定的CacheLoader自动装载进去
    Integer age2 = cache.get("张三");
    System.out.println(age2);
}
null
自动填充:张三
18

2.3 异步手动(Asynchronous Manual)

public static void main(String... args) throws Exception {
    AsyncCache<String, Integer> cache = Caffeine.newBuilder().buildAsync();

    //会返回一个 future对象, 调用future对象的get方法会一直卡住直到得到返回,和多线程的submit一样
    CompletableFuture<Integer> ageFuture = cache.get("张三", name -> {
        System.out.println("name:" + name);
        return 18;
    });

    Integer age = ageFuture.get();
    System.out.println("age:" + age);
}
name:张三
age:18

2.4 异步自动(Asynchronously Loading)

public static void main(String... args) throws Exception {
    //和1.4基本差不多
    AsyncLoadingCache<String, Integer> cache = Caffeine.newBuilder().buildAsync(name -> {
        System.out.println("name:" + name);
        return 18;
    });
    CompletableFuture<Integer> ageFuture = cache.get("张三");

    Integer age = ageFuture.get();
    System.out.println("age:" + age);
}
name:张三
age:18

3. 驱逐策略

3.1 基于容量大小

public static void main(String... args) throws Exception {
    Cache<String, Integer> cache = Caffeine.newBuilder().maximumSize(10)
    .removalListener((key, value, cause) -> {
        System.out.println(String.format("key %s was removed %s / %s", key, value, cause));
    }).build();

    for (int i = 0; i < 100; i++) {
        cache.put("name" + i, i);
    }
    Thread.currentThread().join();
}
key name0 was removed 0 / SIZE
key name3 was removed 3 / SIZE
key name4 was removed 4 / SIZE
key name5 was removed 5 / SIZE
key name39 was removed 39 / SIZE
key name38 was removed 38 / SIZE
key name37 was removed 37 / SIZE
key name36 was removed 36 / SIZE
key name35 was removed 35 / SIZE
key name34 was removed 34 / SIZE
key name33 was removed 33 / SIZE
key name32 was removed 32 / SIZE
...

3.2 基于时间

//写入后10秒过期,重新写入会刷新过期时间
Cache<String, Integer> cache1 = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
//写入或读取后10秒无任务操作会过期,读写都会刷新过期时间
Cache<String, Integer> cache2 = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS).build();
### 使用 Caffeine 构建 Java 缓存的最佳实践 Caffeine 是一个高效且易于使用的缓存库,适用于需要高性能缓存解决方案的应用程序。以下是关于如何使用 Caffeine 构建缓存的一些最佳实践以及示例代码。 #### 1. 创建基本缓存 通过 `Caffeine.newBuilder()` 方法可以创建一个新的缓存构建器,并设置各种参数以满足特定需求[^3]。以下是一个简单的例子: ```java import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; public class BasicCacheExample { public static void main(String[] args) { // 创建新的缓存对象 Cache<String, String> cache = Caffeine.newBuilder() .maximumSize(10_000) // 设置最大条目数 .expireAfterWrite(10, java.util.concurrent.TimeUnit.MINUTES) // 设置写入后过期时间 .build(); // 添加键值对到缓存中 cache.put("key", "value"); // 获取缓存中的值 System.out.println(cache.getIfPresent("key")); // 输出 value } } ``` 此代码片段展示了如何初始化一个具有固定大小和过期策略的缓存实例。 --- #### 2. 集成 Spring Boot 中的 Caffeine 缓存 当在 Spring Boot 应用程序中集成 Caffeine 时,可以通过配置文件启用并自定义缓存行为[^4]。下面是如何实现的一个典型场景: ##### (a) 修改 application.yml 文件 ```yaml server: port: 8100 servlet: encoding: charset: UTF-8 force: true spring: cache: type: caffeine ``` ##### (b) 启用缓存支持 在主类或控制器类上添加 `@EnableCaching` 注解以激活缓存功能: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` ##### (c) 定义缓存方法 利用 `@Cacheable` 和其他相关注解简化数据访问逻辑: ```java import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class UserService { @Cacheable(value = "users", key = "#id") public User getUserById(Long id) { // 假设这是一个耗时操作 return fetchUserFromDatabase(id); // 实际数据库查询逻辑省略 } private User fetchUserFromDatabase(Long id) { // 数据库模拟读取 return new User(id, "John Doe"); } } class User { private Long id; private String name; public User(Long id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "User{id=" + id + ", name='" + name + "'}"; } } ``` 上述代码说明了如何将用户信息存储到缓存中,从而减少重复调用昂贵的操作次数。 --- #### 3. 自定义缓存加载与刷新策略 除了默认的行为外,还可以指定更复杂的加载机制或者监听事件以便于动态更新缓存内容。例如: ```java import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.RemovalListener; LoadingCache<Long, User> userCache = Caffeine.newBuilder() .removalListener((RemovalListener<Long, User>) (key, value, cause) -> { System.out.println("Removed Key:" + key + "; Cause:" + cause); }) .build(key -> loadUserFromDatabase(key)); // 当未命中时自动触发加载函数 private User loadUserFromDatabase(Long userId) { // 模拟从外部资源获取数据的过程 return new User(userId, "Dynamic Name-" + userId); } ``` 这里引入了一个移除监听器用于跟踪哪些项被清除掉;同时也设置了异步加载规则,在首次请求不存在的数据之前会先尝试计算出来再返回给调用方。 --- ### 总结 以上就是有关于怎样运用 Caffeine 来建立有效的 Java 缓存系统的几个方面介绍及其对应的样例演示[^1][^2][^4]。希望这些资料能够对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值