zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Caffeine缓存框架入门学习

2023-03-31 10:54:12 时间

引入依赖

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.5.5</version>
</dependency>

基础创建方式

Cache<String, Integer> cache = Caffeine.newBuilder().build();

常用创建模板

private static final Cache<String, String> CONFIG_VALUE =
            Caffeine.newBuilder()
                    //初始容量
                    .initialCapacity(100)
                    //最大容量
                    .maximumSize(1000)
                    //过期时间
                    .expireAfterWrite(10, TimeUnit.MINUTES)
                    //缓存元素删除监听器,参数分别为缓存的key,value,驱逐原因
                    .removalListener((Key key, Object value, RemovalCause cause) ->
                            System.out.printf("Key %s was removed (%s)%n", key, cause))
                    .build();

填充策略

填充策略分为手动填充,自动填充,异步手动填充和异步自动填充四种

  • 手动填充
Cache<Key, MyObject> cache = Caffeine.newBuilder().build();

// 查找一个缓存元素, 没有查找到的时候返回null
MyObject graph = cache.getIfPresent(key);
// 查找缓存,如果缓存不存在则生成缓存元素,  如果无法生成则返回null
graph = cache.get(key, k -> createObject(key));
// 添加或者更新一个缓存元素
cache.put(key, graph);
// 移除一个缓存元素
cache.invalidate(key);
  • 自动填充
LoadingCache<Key, Graph> cache = Caffeine.newBuilder()
    //自动填充即在初始化的时候就指定自动填充函数,当缓存中没有命中数据的时候自动执行填充函数
    .build(key -> createExpensiveGraph(key));

// 查找缓存,如果缓存不存在则生成缓存元素,  如果无法生成则返回null
Graph graph = cache.get(key);
// 批量查找缓存,如果缓存不存在则生成缓存元素
Map<Key, Graph> graphs = cache.getAll(keys);
  • 异步手动填充
AsyncCache<Key, Graph> cache = Caffeine.newBuilder()
    .buildAsync();

// 查找缓存元素,如果不存在,则异步生成
CompletableFuture<Graph> graph = cache.get(key, k -> createExpensiveGraph(key));
  • 异步自动填充
AsyncLoadingCache<Key, Graph> cache = Caffeine.newBuilder()
    // 你可以选择: 去异步的封装一段同步操作来生成缓存元素
    .buildAsync(key -> createExpensiveGraph(key));
    // 你也可以选择: 构建一个异步缓存元素操作并返回一个future
    .buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));

// 查找缓存元素,如果其不存在,将会异步进行生成
CompletableFuture<Graph> graph = cache.get(key);
// 批量查找缓存元素,如果其不存在,将会异步进行生成
CompletableFuture<Map<Key, Graph>> graphs = cache.getAll(keys);

驱逐策略

驱逐策略有三种:基于大小驱逐,基于时间驱逐,基于引用驱逐

  • 基于大小分为基于缓存大小,和基于权重大小两种
// 根据缓存的计数进行驱逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumSize(10_000)
    .build(key -> createExpensiveGraph(key));

// 根据缓存的权重来进行驱逐(权重只是用于确定缓存大小,不会用于决定该缓存是否被驱逐)
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumWeight(10_000)
    .weigher((Key key, Graph graph) -> graph.vertices().size())
    .build(key -> createExpensiveGraph(key));
  • 基于时间驱逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    //当指定时间内没有被读写则被清除
    .expireAfterAccess(5, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    //最后一次写入固定时间后被清除
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));

//还可以使用exoureAfter()来自定义到期驱逐策略,详见文章末尾参考链接
  • 基于引用驱逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    //弱引用键值
    .weakKeys()
    .weakValues()
    .build(key -> createExpensiveGraph(key));

// 当垃圾收集器需要释放内存时驱逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    //软引用值
    .softValues()
    .build(key -> createExpensiveGraph(key));

注意:AsyncLoadingCache不支持弱引用和软引用。


以上仅为基础部分内容,详细学习参考文末链接。

参考:
https://blog.csdn.net/crazymakercircle/article/details/113751575
https://zhuanlan.zhihu.com/p/329684099