Guava Cache实战—从场景使用到原理分析

本文深入探讨Guava Cache在多线程高并发场景中的使用,包括为何选择本地缓存,Guava Cache的接入步骤,以及常见问题。通过分析Guava Cache的底层数据结构和缓存清理策略,揭示其高性能原因。文章还提出了优化方向,如使用Caffeine作为替代,并介绍了Caffeine的优化机制和优势。

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

摘要:本文先介绍为什么使用 Guava Cache 缓存;然后讲解 Guava 缓存使用方法、清理方法及使用过程中踩过的坑;接着讲解其底层数据结构,分析其性能优异的原因;最后讲解在使用本地缓存时可以优化的方向。

为什么使用本地缓存

在多线程高并发场景中往往是离不开 cache 的,需要根据不同的应用场景来需要选择不同的 cache,比如分布式缓存如 Redis、memcached,还有本地(进程内)缓存如 ehcache、Guava Cache。缓存相比IO操作,速度快,效率高;Guava 相比 Redis 来说,应用和cache是在同一个进程内部,请求缓存非常迅速,没有过多的网络开销。redis 的好处是自身就是一个独立的应用,多个应用可以共享缓存。我们应该根据数据类型、业务场景来判断应该使用哪种类型的缓存,以达到减少计算量,提高响应速度的目的。

在这里插入图片描述

本地缓存适用场景(需都满足)

  • 愿意消耗一些内存空间来提升速度

  • 预料到某些键会被多次查询

  • 缓存中存放的数据总量不会超出内存容量

  • 要更快的响应,缓存不需要网络 io(集中式缓存需要额外网络 io)

如何使用 Guava 缓存

Guava Cache 是 Google 开源的 Java 重用工具集库 Guava 里的一款缓存工具,下面介绍接入 guava 缓存的步骤及使用过程中踩过的坑

Guava Cache 接入demo

  • 1、导入 Maven 引用
<dependency>  
    <groupId>com.google.guava</groupId>  
    <artifactId>guava</artifactId>
    <version>19.0</version>  
</dependency> 
  • 2、Cache 初始化,使用了 Builder 设计模式,可自行设置各类参数
private final LoadingCache<Long, TestDemo> demo = CacheBuilder.newBuilder()  
        //设置 cache 的初始大小为10,要合理设置该值  
        .initialCapacity(10)  
        //设置并发数为5,即同一时间最多只能有5个线程往 cache 执行写入操作  
        .concurrencyLevel(5) 
        //最大 key 个数
        .maximumSize(100)
        //移除监听器
        .removalListener(removalListener)
        //设置 cache 中的数据在写入之后的存活时间为10秒  
        .expireAfterWrite(10, TimeUnit.SECONDS)  
        //构建 cache 实例  
        .build(new CacheLoader<Long, TestDemo>() {
              @Override
              public TestDemo load(Long id) throws Exception {
                  // 读取 db 数据
              }
}); 
                 
RemovalListener<String, String> removalListener = new RemovalListener<String, String>() {
    public void onRemoval(RemovalNotification<id, TestDemo> removal) {
		System.out.println("[" + removal.getKey() + ":" + removal.getValue() + removal.getCause() +  "] is evicted!");
    }
};
  • 3、 如果缓存加载方法时出现了异常,那么下一次是缓存异常还是正常数据?
public class TestDemoImpl implements TestDemo {
  int time;
	private final LoadingCache<Long, TestDemo> demo;
    this.demo1 = CacheBuilder.newBuilder()
          .expireAfterWrite(duration, TimeUnit.HOURS)
          .build(new CacheLoader<Long, TestDemo>() {
                @Override
                 public TestDemo load(Long id) throws Exception {
                     // 查询 db
                     if (time++==0) {
                         throw new RunTimeException();
                     }
                     return result;
                 }
             });
}
 public static void main(String[] args) {
      try {
          try {
              TestDemo testDemo = demoCache.getUnchecked(21L);
              System.out.println("第一次查询:" + testDemo);
          } catch (Exception e) {
          }
           TestDemo testDemo1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值