`

Guava Cache使用笔记

阅读更多
1.Guava Cache的get/getIfPresent方法当参数为null时会抛空指针异常

我刚开始使用时还以为Guava Cache跟HashMap一样,get(null)返回null。
实际上Guava整体设计思想就是拒绝null的,很多地方都会执行com.google.common.base.Preconditions.checkNotNull的检查。

2.Guava Cache的load方法不能返回null,否则抛异常

Guava Cache的get方法先在本地缓存中取,如果不存在,则会触发load方法。但load方法不能返回null。

设想这样一个场景:进行某些热点数据查询时,如果缓存中没有,则去数据库中查询,并把查询到的结果保存到缓存中。
但假如说数据库中也没有呢?
这个时候load方法就会抛异常,例如:
public enum TestGuavaCache {

    INSTANCE;

    private LoadingCache<String, Person> infos;

    TestGuavaCache() {
        infos = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(new CacheLoader<String, Person>() {
            public Person load(String key) throws Exception {
                //load from database
                Person p = loadFromDatabase();
                return p;
            }
        });
    }

	//假设数据库中不存在
    private Person loadFromDatabase() {
        return null;
    }

    public Person get(String key) {
        try {
            return infos.get(key);
        } catch (Exception e) {
            //log exception
        }
        return null;
    }
}

这是因为Guava Cache认为cache null是无意义的,因此Guava Cache的javadoc里加粗说明:must not be null

现实世界没那么理想,肯定会有null的情况,那怎么处理呢?我的处理一般是对Guava Cache的get方法做try-catch。


有时候cache null也是有意义的,例如对于一个key,假如数据库中也没有对应的value,那就把这个情况记录下来,
避免频繁的查询数据库(例如一些攻击性行为),直接在缓存中就把这个key挡住了。
怎么做呢?举例:

@Test
public void whenNullValue_thenOptional() {
    CacheLoader<String, Optional<String>> loader;
    loader = new CacheLoader<String, Optional<String>>() {
        @Override
        public Optional<String> load(String key) {
            return Optional.fromNullable(getSuffix(key));
        }
    };
 
    LoadingCache<String, Optional<String>> cache;
    cache = CacheBuilder.newBuilder().build(loader);
 
    assertEquals("txt", cache.getUnchecked("text.txt").get());
    assertFalse(cache.getUnchecked("hello").isPresent());
}
private String getSuffix(final String str) {
    int lastIndex = str.lastIndexOf('.');
    if (lastIndex == -1) {
        return null;
    }
    return str.substring(lastIndex + 1);
}


3.什么时候用get,什么时候用getUnchecked

官网文档说:
. If you have defined a CacheLoader that does not declare any checked exceptions then you can perform cache lookups using getUnchecked(K); 
however care must be taken not to call getUnchecked on caches whose CacheLoaders declare checked exceptions.

字面意思是,如果你的CacheLoader没有定义任何checked Exception,那你可以使用getUnchecked。
这一段话我也不是很理解。。官网上给了一个例子是,load方法没有声明throws Exception,那就可以使用getUnchecked:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .expireAfterAccess(10, TimeUnit.MINUTES)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) { // no checked exception
               return createExpensiveGraph(key);
             }
           });

...
return graphs.getUnchecked(key);


4.如何定义一个普通的Guava Cache,不需要用到load方法

假如只是简单的把Guava Cache当作HashMap或ConcurrentHashMap的替代品,不需要用到load方法,而是手动地插入,可以这样:
com.google.common.cache.Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build();

注意不能用LoadingCache了。
查找:
cache.getIfPresent("xx");
插入:
cache.put("xx", "xxx");

5.Guava Cache的超时机制不是精确的。

我曾经依赖Guava Cache的超时机制和RemovalListener,以实现类似定时任务的功能;后来发现Guava Cache的超时机制是不精确的,例如你设置cache的缓存时间是30秒,
那它存活31秒、32秒,都是有可能的。
官网说:
Timed expiration is performed with periodic maintenance during writes and occasionally during reads, as discussed below.
Caches built with CacheBuilder do not perform cleanup and evict values "automatically," or instantly after a value expires, or anything of the sort. 
Instead, it performs small amounts of maintenance during write operations, or during occasional read operations if writes are rare.







2
0
分享到:
评论

相关推荐

    Guava-Cache本地缓存案例代码

    本案例代码将详细介绍Guava Cache的使用,包括缓存的创建、删除、获取、失效监听、加载以及淘汰策略。 1. **缓存创建**: Guava Cache可以通过CacheBuilder类创建。CacheBuilder提供了丰富的配置选项,如最大容量...

    guava-cache.rar

    》这篇博客中,作者详细介绍了如何利用Guava Cache作为本地缓存来补充或增强分布式缓存的使用。 1. **初始化Guava Cache** 初始化Guava Cache时,可以通过`LoadingCache`接口创建一个自定义配置的缓存实例。例如,...

    Springboot整合GuavaCache缓存过程解析

    SpringBoot整合GuavaCache缓存过程解析是指使用SpringBoot框架将GuavaCache整合到应用程序中,以提高应用程序的性能和响应速度。 GuavaCache的优点是: * 简单:GuavaCache的使用非常简单,只需要在pom.xml文件中...

    Go-Localcaching-GuavaCache在Go中的部分的实现

    Guava Cache是Java领域广泛使用的高效缓存解决方案,但Go语言本身并未直接提供与Guava Cache类似的功能。然而,开发者可以借鉴Guava Cache的设计理念,使用Go的标准库或者其他第三方库来实现类似的本地缓存机制。`...

    SpringBoot加入Guava Cache实现本地缓存代码实例

    在本文中,我们将介绍如何在 SpringBoot 项目中使用 Guava Cache 实现本地缓存。Guava Cache 是一个高性能的缓存框架,由 Google 开发维护。它提供了一个灵活的缓存机制,可以根据实际需求进行配置。 首先,我们...

    详解Guava Cache本地缓存在Spring Boot应用中的实践

    在使用Guava Cache之前,需要在pom.xml文件中添加相应的依赖,包括Spring Boot、MyBatis、MySQL和Guava Cache等。在配置Guava Cache时,需要创建一个GuavaCacheConfig配置类,并在其中设置CacheManager。 ...

    第七章 企业项目开发--本地缓存guava cache1

    一、Guava Cache的基本使用 1. 引入依赖 在项目中引入Guava库,如pom.xml文件中添加如下依赖: ```xml &lt;groupId&gt;com.google.guava&lt;/groupId&gt; &lt;artifactId&gt;guava &lt;version&gt;14.0.1 ``` 请注意,版本号可能需要...

    Guava-CacheDemo.rar

    Guava Cache是Google Guava库中的一个功能强大的本地缓存实现,它为Java开发者提供了高效、易用的缓存解决方案。...通过学习和熟练使用Guava Cache,开发者可以更好地优化应用程序的性能,提升用户体验。

    springboot使用GuavaCache做简单缓存处理的方法

    SpringBoot 使用 GuavaCache 实现简单缓存处理 在本篇文章中,我们将介绍如何使用 GuavaCache 在 SpringBoot 项目中实现简单的缓存处理。缓存机制可以减少对外部服务的查询请求,从而提高应用程序的性能。 问题...

    使用google guava 实现定时缓存功能

    创建一个Guava Cache对象,你可以通过`LoadingCache`接口,它在缓存项缺失时会自动加载。例如: ```java LoadingCache, Graph&gt; graphs = CacheBuilder.newBuilder() .maximumSize(1000) // 设置最大缓存容量 ....

    Guava-Cache-Demo:演示如何使用 Guava 缓存

    在这个名为 "Guava-Cache-Demo" 的项目中,我们将深入探讨如何利用 Guava Cache 来实现缓存机制,并通过一个实际示例——使用 Google Books API 获取 ISBN 对应图书详情——来展示其用法。 首先,我们需要理解 ...

    Java内存缓存工具Guava LoadingCache使用解析

    Java内存缓存工具Guava LoadingCache使用解析 Java内存缓存工具Guava LoadingCache是一个非常强大的缓存工具,广泛应用于各种Java项目中。Guava Cache是单个应用运行时的本地缓存,用于将数据缓存到JVM内存中,提高...

    springbt_guava_cache.7z

    本文将深入探讨如何在Spring Boot项目中集成并使用Guava Cache,以实现高效、灵活的缓存策略。 一、Spring Boot与Guava Cache简介 1. Spring Boot:作为Spring框架的微服务启动器,Spring Boot简化了Java应用的...

    Mango Cache-Go中的Guava Cache的部分实现。-Golang开发

    Go中的Guava Cache的Mango Cache部分实现。 支持的缓存替换策略:LRU分段LRU(默认)TinyLFU(实验性)TinyLFU实现的灵感源于Ben Manes的Caffeine和Go中的Guava Cache的Mango Cache Partial实现。 支持的缓存替换...

    guava使用方法教程

    guava 使用方法 教程

    不加密Google Guava视频教程.txt

    ├─Google Guava 第01讲-Joiner详细介绍以及和Java8Collector对比.wmv ├─Google Guava 第02讲-Guava Splitter详细讲解以及实战练习...├─Google Guava 第34讲-Guava Cache之RecordStats,CacheBuilderSpec详解.wmv

    spring-cache-demo:spring整合guava和redis实现本地和远程缓存

    Guava Cache与Redis的结合使用可以形成一个强大的缓存解决方案。Guava Cache可以作为本地缓存,快速响应,降低延迟,而Redis作为远程缓存,可以在多台服务器间共享数据,提高系统的伸缩性和可靠性。当本地缓存无法...

    DurianCoder#springboot-example#Springboot集成GuavaCache实现本地缓存1

    Springboot集成本地缓存Guava本章介绍一个比较好用的本地缓存Guava0x01、添加依赖0x02、添加GuavaLocalCache提供了设置超时时

    Guava使用培训教程

    ### Guava概述 Guava是Google推出的一款Java核心类库,旨在通过添加一系列经过充分测试且高度实用的工具集来优化Java...对于任何希望提高开发效率和代码质量的Java开发者来说,Guava都是一个值得深入学习和使用的库。

Global site tag (gtag.js) - Google Analytics