美文网首页
guava 本地缓存

guava 本地缓存

作者: 梦醒时见你sd | 来源:发表于2021-07-02 14:31 被阅读0次

    介绍

    Guava cache是本地缓存的一种实现。

    Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也是很有用的,因为它会自动加载缓存。

    应用场景

    • 对读取性能要求高,空间换时间,愿意消耗一定的内存空间来提高读取速度
    • 预测到会存在热数据,会进行频繁的读取操作
    • 缓存数据不会超过内存容量
      (Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试Memcached、Redis这类工具)
    注:如果你不需要Cache中的特性,使用ConcurrentHashMap有更好的内存效率

    如何使用

    pom依赖

    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>20.0</version>
    </dependency>
    

    Cache

    示例:

    Cache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(2)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build();
        cache.put("a","a");
        String a = cache.getIfPresent("a");
        Thread.sleep(10000);
        String a2 = cache.getIfPresent("a");
        System.out.println(a);
        System.out.println(a2);
    

    结果:

     a
     null
    

    LoadCache

    示例2:

      //模拟数据源
      public static  ConcurrentHashMap<String, String> map=new ConcurrentHashMap<String, String>();
    {
        map.put("a", "a");
        map.put("v", "v");
        map.put("b", "b");
        map.put("d", "d");
        map.put("f", "f");
        map.put("e", "e");
    }
    
    @Test
    void createGuavaLoadCache() throws Exception{
        LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
                .maximumSize(2)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String s) throws Exception {
                        System.out.println("从源数据加载:"+s);
                        String s1 = map.get(s);
                        return StringUtils.isBlank(s1) ? "" : s1;//Q1.注:此处需判空,不能返回null,会报错 
                    }
                });
    
       String a = loadingCache.get("a");
        System.out.println(a);
        a = loadingCache.get("a");
        System.out.println("测试本地缓存读取:"+a);
        String b = loadingCache.get("b");
        System.out.println(b);
        String c = loadingCache.get("c");
        System.out.println(c);
        c = loadingCache.get("c");
        System.out.println(c);
        //测试最大容量
        a = loadingCache.get("a");
        System.out.println("测试最大容量,从源数据读取:"+a);
        Thread.sleep(10000);
        //测试过期回收
        String a2 = loadingCache.get("a");
        System.out.println("测试过期回收,从源数据读取:"+a2);
    }
    

    运行结果:

     com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key c.
    

    抛出异常,原因是读取"c"时没有值,从CacheLoader加载源数据到本地缓存返回为null,所以我们需要在CacheLoader的load方法里增加空判断( Q1处),不能返回null。

    增加判空后:

    从源数据加载:a
    a
    测试本地缓存读取:a
    从源数据加载:b
    b
    从源数据加载:c
    
    
    从源数据加载:a
    测试最大容量,从源数据读取:a
    从源数据加载:a
    测试过期回收,从源数据读取:a
    

    相关文章

      网友评论

          本文标题:guava 本地缓存

          本文链接:https://www.haomeiwen.com/subject/senviktx.html