本地缓存方案Guava Cache

Guava Cache 是 Google 的 Guava 库提供的一个高效内存缓存解决方案,适用于需要快速访问且不频繁变更的数据。

// 普通缓存
Cache<Key, Value> cache = CacheBuilder.newBuilder()
    .maximumSize(1000) // 最大条目数
    .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
    .recordStats() // 开启统计
    .build();

// 自动加载缓存(LoadingCache)
LoadingCache<Key, Value> loadingCache = CacheBuilder.newBuilder()
    .maximumWeight(10_000)
    .weigher((Key k, Value v) -> v.size()) // 按值大小计算权重
    .build(new CacheLoader<Key, Value>() {
        @Override
        public Value load(Key key) throws Exception {
            return loadDataFromDataSource(key); // 缺失时自动加载
        }
    });

2. 核心操作

// 手动放入缓存
cache.put(key, value);

// 获取缓存(缺失时返回null)
Value value = cache.getIfPresent(key);

// 获取并自动加载(LoadingCache)
Value value = loadingCache.get(key); // 若缺失,调用CacheLoader.load()

// 手动移除
cache.invalidate(key);
cache.invalidateAll(); // 清空所有缓存

3. 过期策略

  • 时间驱动​:
    • expireAfterWrite(duration):写入后指定时间过期。
    • expireAfterAccess(duration):最后一次访问后指定时间过期。
  • 容量驱动​:
    • maximumSize(long):基于LRU策略淘汰条目。
    • maximumWeight(long) + weigher:按条目权重计算总容量。

4. 自动加载(LoadingCache)​

  • 同步加载​:通过 CacheLoader.load() 方法在缓存未命中时同步加载数据。
  • 批量加载​:重写 loadAll(Iterable<? extends K> keys) 提升多键加载效率。
  • 异步刷新​:使用 refreshAfterWrite(duration) 在后台异步刷新过期条目,避免阻塞读取。

5. 移除监听器(RemovalListener)​

监听缓存条目被移除的事件,执行资源释放等操作:

RemovalListener<Key, Value> listener = notification -> {
    if (notification.wasEvicted()) {
        // 处理资源释放
    }
};

Cache<Key, Value> cache = CacheBuilder.newBuilder()
    .removalListener(listener)
    .build();

6. 统计信息

通过 recordStats() 启用统计,获取命中率、加载时间等数据:

Cache<?, ?> cache = CacheBuilder.newBuilder().recordStats().build();
// ...
CacheStats stats = cache.stats();
double hitRate = stats.hitRate(); // 命中率
long missCount = stats.missCount(); // 未命中次数

7. 线程安全

Guava Cache 默认线程安全,支持高并发读写,无需额外同步。


8. 异常处理

  • CacheLoader 中抛出的异常会被封装为 UncheckedExecutionException
  • 建议在 load 方法中捕获异常,或通过 getUnchecked() 处理。

9. 使用场景

  • 高频读取,低频变更​:如配置信息、用户会话。
  • 计算密集型数据​:避免重复计算(如复杂查询结果)。
  • 资源敏感场景​:通过权重控制内存占用。

示例代码

LoadingCache<String, String> cache = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .expireAfterAccess(5, TimeUnit.MINUTES)
    .recordStats()
    .build(new CacheLoader<String, String>() {
        @Override
        public String load(String key) {
            return fetchDataFromDB(key); // 缺失时从数据库加载
        }
    });

// 使用缓存
try {
    String data = cache.get("user:123");
} catch (ExecutionException e) {
    // 处理加载异常
}

// 手动刷新
cache.refresh("user:123");

通过合理配置策略,Guava Cache 能有效平衡内存使用与性能,是 Java 应用中轻量级缓存的优选方案。

Guava Cache是Google Guava库中提供的一种本地缓存解决方案。它是一个基于内存的缓存,可以在应用程序内部存储数据,提高应用程序性能。 Guava Cache提供了以下特性: 1. 自动加载:当缓存中不存在某个键的值时,可以自动加载生成该值。 2. 自动移除:缓存中的某些条目可以在一定时间内自动过期,或者可以使用大小限制来限制缓存中的条目数。 3. 针对不同的缓存数据设置不同的过期时间、存活时间、最大值、最小值等。 4. 支持同步和异步缓存。 使用Guava Cache非常简单,只需要按以下步骤操作: 1. 引入Guava库。 2. 创建一个CacheBuilder对象,用于配置缓存。 3. 调用build()方法创建一个Cache对象。 4. 使用put()方法向缓存中添加数据。 5. 使用get()方法从缓存中读取数据,如果缓存中不存在该键对应的值,则可以自动加载。 6. 使用invalidate()方法从缓存中移除数据。 下面是一个简单的示例: ```java import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; public class GuavaCacheExample { public static void main(String[] args) throws ExecutionException { // 创建一个CacheBuilder对象 CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder() .maximumSize(100) // 设置缓存最大条目数 .expireAfterWrite(10, TimeUnit.MINUTES); // 设置缓存过期时间 // 创建一个Cache对象 LoadingCache<String, String> cache = cacheBuilder.build(new CacheLoader<String, String>() { @Override public String load(String key) throws Exception { System.out.println("loading " + key); // 自动加载数据 return "value-" + key; } }); // 添加数据到缓存cache.put("key1", "value1"); cache.put("key2", "value2"); // 从缓存中读取数据 System.out.println(cache.get("key1")); // 输出"value1" System.out.println(cache.get("key3")); // 输出"loading key3"和"value-key3" // 移除缓存中的数据 cache.invalidate("key1"); System.out.println(cache.get("key1", () -> "default")); // 输出"default" } } ``` 在这个示例中,我们使用CacheBuilder对象配置了缓存的最大条目数和过期时间。我们还使用CacheLoader对象创建了一个自动加载的缓存,当缓存中不存在某个键的值时,可以自动加载生成该值。我们使用put()方法向缓存中添加了两个数据,使用get()方法从缓存中读取了两个数据,并使用invalidate()方法从缓存中移除了一个数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值