Guava 缓存库 Cachebuilder 使用和原理

CacheBuilder是Guava库中的核心组件,用于创建和配置缓存。它支持链式调用配置,如设置最大容量、过期时间和弱引用。此外,还提供缓存统计、定时刷新以及自定义缓存加载器等功能。通过示例展示了如何构建和使用LoadingCache,并解释了数据存储、查询、过期和刷新的基本原理。

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

Guava 缓存库 Cachebuilder 使用和原理

简介

CacheBuilder 是 Guava 缓存库(Google 提供的一个 Java 工具库)中的一个类,用于创建和配置缓存实例。
Guava 缓存库提供了一套强大且易用的缓存解决方案,可以帮助开发者轻松地添加缓存功能以提高程序性能。而 CacheBuilder 是其中一个关键的构建器类,它提供了多种方法用于配置和创建缓存实例。
下面是 CacheBuilder 的一些主要特点和功能:
链式调用:CacheBuilder 允许通过链式调用方法来配置缓存的各项参数,使得配置变得简洁明了。
缓存大小限制:可以通过 maximumSize(long) 方法指定缓存的最大容量,当缓存超过指定容量时,会按照一定的策略(例如LRU)进行缓存项的清理。
过期时间设置:使用 expireAfterWrite(duration, unit) 方法可以为缓存项设定写入后过期时间,即在一定时间后自动从缓存中移除。
弱引用键或值:可以使用 weakKeys() 和 weakValues() 方法将缓存的键或值设置为弱引用,这样当没有其他强引用指向它们时,垃圾回收器可以自动回收这些对象。
定时刷新:使用 refreshAfterWrite(duration, unit) 方法可以为缓存项设置定时刷新,即在一定时间后自动更新缓存项的值,避免了缓存过期时的数据加载延迟。
统计信息:CacheBuilder 提供了统计缓存命中率等信息的功能,可以通过 recordStats() 方法开启统计,并通过 Cache.stats() 方法获取统计信息。
自定义缓存加载器:可以通过 build(CacheLoader) 方法传入自定义的缓存加载器,用于指定缓存项的加载逻辑。

使用实例

public class CacheTest {
    LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .expireAfterAccess(10, TimeUnit.MINUTES)
            .build(
                    new CacheLoader<String, String>() {
                        @Override
                        public String load(String String) {
                            return "value-"+ LocalTime.now();
                        }
                    }
            );
    public static void main(String[] args){
        CacheTest cacheTest = new CacheTest();
        System.out.println(cacheTest.getV("aa"));
        System.out.println(cacheTest.getV("bb"));
        System.out.println(cacheTest.getV("aa"));
    }
    public String getV(String key){
        try {
            return cache.get(key);
        } catch (ExecutionException e) {
           e.printStackTrace();
        }
        return "null";
    }
}

基本原理

数据存储和查询

Guava 缓存库的数据存储主要分了两级,第一级是 Segment ,第二级是 AtomicReferenceArray
Segment 是 Guava 实现的 LocalCache 的子类,LocalCache 中有一个 Segment 数组 segments ,对于每一个缓存的键值 key ,都可以通过 key 的hash找出唯一的Segment
Segment 中有一个 AtomicReferenceArray 类型变量 table,table 的元素类型是 ReferenceEntry , ReferenceEntry 是Guava对缓存值的包装类型,并包含了缓存的访问时间,写入时间等信息
查询时:先通过key的hash定位到一个Segment,segments 数组中的每个元素是在LocalCache被创建时就初始化好的。再从 Segment 的 table 中遍历查找 hash 和 key 的hash相同的元素链表,再遍历链表使用类似 equals 方法找到最终的缓存值。查找过程除 Segment 外类似 hashmap 。Segment的作用类似 concurrenthashMap 中Segment 的作用,都是为了提高并发度。 若没有找到值,则调用使用者自定义的 CacheLoader 类中的 load() 方法加载缓存。

过期和刷新

Guava 缓存好用的特点之一是提供了各种缓存过期和刷新策略,其基本原理是缓存包装类 ReferenceEntry 中记录了缓存值的各种时间,如创建时间,访问时间。在查询到缓存值后,对比当前时间与这些时间的差值和使用者设置的过期时间,若超时则重新调用缓存加载方法加载新缓存。

### Java中的缓存机制 #### 使用Guava Cache实现简单的缓存功能 Google Guava提供了一种简单而强大的方式来创建本地缓存。通过`CacheBuilder`类可以方便地配置构建缓存实例。 ```java import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; public class GuavaCacheExample { private static final int MAX_ENTRIES = 100; // 设置最大条目数 public static void main(String[] args) throws Exception { Cache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(MAX_ENTRIES) .build(); // 添加键值对到缓存中 cache.put("key", "value"); // 获取指定键对应的值 System.out.println(cache.getIfPresent("key")); } } ``` 此代码片段展示了如何利用Guava快速搭建起具有自动过期特性的内存级缓存系统[^1]。 #### 实现LRU(最近最少使用)策略的自定义缓存 为了更深入理解缓存的工作原理,下面给出基于双向链表与哈希映射的数据结构手动编写的一个简易版LRU缓存: ```java import java.util.LinkedHashMap; import java.util.Map; class LRUCache<K,V> extends LinkedHashMap<K,V>{ private final int capacity; public LRUCache(int capacity){ super(capacity, 0.75f,true); this.capacity=capacity; } @Override protected boolean removeEldestEntry(Map.Entry eldest){ return size()>capacity; } } // 测试LRU缓存 public class TestLRUCache { public static void main(String[] args) { LRUCache<Integer,String> lru=new LRUCache<>(3); lru.put(1,"A"); lru.put(2,"B"); lru.put(3,"C"); System.out.println(lru); // 输出 {1=A, 2=B, 3=C} lru.get(1); // 访问 key=1 的元素 lru.put(4,"D"); // 插入新数据项 (超过容量) System.out.println(lru); // 输出 {2=B, 3=C, 4=D} ,最久未使用的Key被移除 } } ``` 上述程序实现了基本的LRU逻辑,在每次访问某个entry时都会调整其位置至队列头部;当达到预设的最大尺寸后,则会淘汰掉最早加入的那个节点][^[^23]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值