GuavaCache缓存

738 阅读2分钟

1 简介

GuavaCache为我们提供了一个本地缓存,他类似于ConcurrentMap。两者最大的区别在于Map中的元素在显示地清除之前会一直保存,而GuavaCache能够限制缓存中元素的数量并设置过期时间。通常来说,GuavaCache适用于以下情况:

  • 愿意消耗一些内存空间来提升速度
  • 预料到某些键会被查询一次以上
  • 缓存中存放的数据总量不会超出内存容量 而事实上,GuavaCache的设计灵感也来源于ConcurrentHashMap,使用多个segments方式的细粒度锁,在保证线程安全的同时,支持高并发场景需求,同时支持多种类型的缓存清理策略,包括基于容量的清理、基于时间的清理、基于引用的清理等。

2 本地缓存 vs 分布式缓存

本地缓存(Local Cache):针对后端应用服务器,本地缓存又叫JVM缓存

  • 优点:其最大的优点是应用和缓存是在同一个进程内部,请求缓存非常快速,没有过多的网络开销

  • 缺点:容量有限,不能存放过多的内容;每个jvm实例都会存一份,存在数据冗余

分布式缓存(Remote Cache):与应用分离的缓存组件或服务,如redis

  • 优点:存储容量大,跟机器有关不受应用影响、缓存全局共享

  • 缺点:存在网络开销,相对于本地缓存存取速度较慢

3 快速入门

3.1 引入依赖

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>28.0-jre</version>
</dependency>

3.2 加载

首先,我们需要构建Cache对象。在GuavaCache中我们可以定义默认的加载规则,也就是说当我们查找一个不存在的key时GuavaCache会按照加载规则帮我们计算出对应的value存入缓存中。

CacheLoader

创建CacheLoader,只需要实现load方法,如下面代码示例。当我们调用get方法获取指定key的缓存值时,如果key的value值还没有缓存,Guava Cache则会自动调用load方法加载value值到缓存并返回。

LoadingCache<String, Object> loadingCache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(3, TimeUnit.SECONDS)
                .build(
                        new CacheLoader<String, Object>() {
                            @Override
                            public Object load(String s) throws Exception {
                                return s + "-" + s;
                            }
                        }
                );
        try {
        	String key = "Hello";
            String result = (String) loadingCache.get(key);
            System.out.println(result);
        } catch (Exception e) {

        }

运行结果:

Hello-Hello

Callable

当然,我们也可为特定的key制定专门的规则。不论我们有没有提供CacheBuilder

LoadingCache<String, Object> loadingCache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(3, TimeUnit.SECONDS)
                .build(
                        new CacheLoader<String, Object>() {
                            @Override
                            public Object load(String s) throws Exception {
                                return s + "-" + s;
                            }
                        }
                );
        try {
            String key = "Hello";
            String result = (String) loadingCache.get(key, new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return key + "+" + key;
                }
            });
            System.out.println(result);
        } catch (Exception e) {

        }

运行结果:

Hello+Hello

3.3 其他接口

直接看中文教程吧,写的比较详细了:wizardforcel.gitbooks.io/guava-tutor…

4 参考

Guava Cache使用介绍:juejin.cn/post/684490…