guava 本地缓存

2021-07-02  本文已影响0人  梦醒时见你sd

介绍

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

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

应用场景

注:如果你不需要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
上一篇 下一篇

猜你喜欢

热点阅读