# Java-缓存-Caffeine
# 使用
依赖:
<!-- spring-boot 已管理该依赖 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.2.0</version>
</dependency>
示例:
import com.github.benmanes.caffeine.cache.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CompletableFuture;
public class CaffeineDemo {
public static void main(String[] args) {
basicUsageDemo();
loadingCacheDemo();
asyncLoadingCacheDemo();
evictionDemo();
statisticsDemo();
}
/**
* 基础缓存操作示例
*/
public static void basicUsageDemo() {
System.out.println("\n=== 1. 基础缓存操作 ===");
Cache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS) // 写入5秒后过期
.maximumSize(100) // 最大100个条目
.build();
// 手动写入
cache.put("key1", "value1");
// 获取值(不存在返回null)
String value = cache.getIfPresent("key1");
System.out.println("获取key1: " + value); // 输出: value1
// 获取或计算(线程安全)
String value2 = cache.get("key2", k -> "computed-" + k);
System.out.println("获取key2: " + value2); // 输出: computed-key2
}
/**
* 自动加载缓存示例
*/
public static void loadingCacheDemo() {
System.out.println("\n=== 2. 自动加载缓存 ===");
LoadingCache<String, String> cache = Caffeine.newBuilder()
.expireAfterAccess(3, TimeUnit.SECONDS) // 3秒未访问则过期
.maximumSize(10)
.build(key -> {
// 模拟从数据库加载
System.out.println("正在加载: " + key);
return "db-value-" + key;
});
// 自动触发加载函数
System.out.println(cache.get("user1001")); // 输出: db-value-user1001
System.out.println(cache.get("user1001")); // 第二次直接从缓存获取
}
/**
* 异步加载缓存示例
*/
public static void asyncLoadingCacheDemo() {
System.out.println("\n=== 3. 异步加载缓存 ===");
AsyncLoadingCache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.SECONDS)
.maximumSize(1000)
.buildAsync(key -> {
// 模拟异步加载
return CompletableFuture.supplyAsync(() -> {
System.out.println("异步加载: " + key);
return "async-value-" + key;
});
});
// 异步获取
cache.get("id123").thenAccept(value -> {
System.out.println("异步获取结果: " + value); // 输出: async-value-id123
});
}
/**
* 淘汰策略示例
*/
public static void evictionDemo() {
System.out.println("\n=== 4. 淘汰策略 ===");
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(3) // 测试用的小容量
.removalListener((key, value, cause) ->
System.out.printf("淘汰事件: key=%s, 原因=%s\n", key, cause))
.build();
cache.put("k1", "v1");
cache.put("k2", "v2");
cache.put("k3", "v3");
cache.put("k4", "v4"); // 触发淘汰(LRU)
System.out.println("当前大小: " + cache.estimatedSize()); // 输出: 3
}
/**
* 统计功能示例
*/
public static void statisticsDemo() {
System.out.println("\n=== 5. 统计功能 ===");
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100)
.recordStats() // 开启统计
.build();
cache.put("k1", "v1");
cache.getIfPresent("k1");
cache.getIfPresent("missingKey");
CacheStats stats = cache.stats();
System.out.println("命中率: " + stats.hitRate()); // 输出: 0.5
System.out.println("命中数: " + stats.hitCount()); // 输出: 1
System.out.println("未命中数: " + stats.missCount()); // 输出: 1
}
}
# 参考
上一篇: 下一篇:
本章目录