前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Guava Cache

Guava Cache

作者头像
黑洞代码
发布2021-04-23 15:00:38
6160
发布2021-04-23 15:00:38
举报
文章被收录于专栏:落叶飞翔的蜗牛

什么是缓存?

根据科普中国的定义,缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。

在这里,我们借用了硬件缓存的概念,当在Java程序中计算或查询数据的代价很高,并且对同样的计算或查询条件需要不止一次获取数据的时候,就应当考虑使用缓存。换句话说,缓存就是以空间换时间,大部分应用在各种IO,数据库查询等耗时较长的应用当中。

缓存原理

当获取数据时,程序将先从一个存储在内存中的数据结构中获取数据。如果数据不存在,则在磁盘或者数据库中获取数据并存入到数据结构当中。之后程序需要再次获取数据时,则会先查询这个数据结构。从内存中获取数据时间明显小于通过IO获取数据,这个数据结构就是缓存的实现。

这里引入一个概念,缓存命中率:从缓存中获取到数据的次数/全部查询次数,命中率越高说明这个缓存的效率好。由于机器内存的限制,缓存一般只能占据有限的内存大小,缓存需要不定期的删除一部分数据,从而保证不会占据大量内存导致机器崩溃。

如何提高命中率呢?那就得从删除一部分数据着手了。目前有三种删除数据的方式,分别是:FIFO(先进先出)、LFU(定期淘汰最少使用次数)、LRU(淘汰最长时间未被使用)。

GuavaCache工作方式

GuavaCache的工作流程:获取数据->如果存在,返回数据->计算获取数据->存储返回。由于特定的工作流程,使用者必须在创建Cache或者获取数据时指定不存在数据时应当怎么获取数据。GuavaCache采用LRU的工作原理,使用者必须指定缓存数据的大小,当超过缓存大小时,必定引发数据删除。GuavaCache还可以让用户指定缓存数据的过期时间,刷新时间等等很多有用的功能。

Demo

代码语言:javascript
复制
public class Man {
    //身份证号
    private String id;
    //姓名
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Man{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}


public class GuavaCachDemo {
    private LoadingCache<String,Man> loadingCache;
    //loadingCache
    public void initLoadingCache() {
        //指定一个如果数据不存在获取数据的方法
        CacheLoader<String, Man> cacheLoader = new CacheLoader<String, Man>() {
            @Override
            public Man load(String key) throws Exception {
                //模拟mysql操作
                System.out.println("LoadingCache测试 从mysql加载缓存ing...(2s)");
                Thread.sleep(2000);
                System.out.println("LoadingCache测试 从mysql加载缓存成功");
                Man tmpman = new Man();
                tmpman.setId(key);
                tmpman.setName("其他人");
                if (key.equals("001")) {
                    tmpman.setName("张三");
                    return tmpman;
                }
                if (key.equals("002")) {
                    tmpman.setName("李四");
                    return tmpman;
                }
                return tmpman;
            }
        };
        //缓存数量为1,为了展示缓存删除效果
        loadingCache = CacheBuilder.newBuilder().maximumSize(1).build(cacheLoader);
    }

    /**
     * 获取数据,如果不存在返回null
     *
     * @param key
     * @return
     */
    public Man getIfPresentloadingCache(String key){
        return loadingCache.getIfPresent(key);
    }

    /**
     * 获取数据,如果数据不存在则通过cacheLoader获取数据,缓存并返回
     *
     * @param key
     * @return
     */
    public Man getCacheKeyloadingCache(String key){
        try {
            return loadingCache.get(key);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 直接向缓存put数据
     *
     * @param key
     * @param value
     */
    public void putloadingCache(String key,Man value){
        System.out.printf("\nput key :%s value : %s\n",key,value.getName());
        loadingCache.put(key,value);
    }
}


// 执行结果:

使用loadingCache
使用loadingCache get方法  第一次加载
LoadingCache测试 从mysql加载缓存ing...(2s)
LoadingCache测试 从mysql加载缓存成功
Man{id='001', name='张三'}

使用loadingCache getIfPresent方法  第一次加载
null

使用loadingCache get方法  第一次加载
LoadingCache测试 从mysql加载缓存ing...(2s)
LoadingCache测试 从mysql加载缓存成功
Man{id='002', name='李四'}

使用loadingCache get方法  已加载过
Man{id='002', name='李四'}

使用loadingCache get方法  已加载过,但是已经被剔除掉,验证重新加载
LoadingCache测试 从mysql加载缓存ing...(2s)
LoadingCache测试 从mysql加载缓存成功
Man{id='001', name='张三'}

使用loadingCache getIfPresent方法  已加载过
Man{id='001', name='张三'}

使用loadingCache put方法  再次get

put key :001 value : 额外添加
Man{id='001', name='额外添加'}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是缓存?
  • 缓存原理
  • GuavaCache工作方式
  • Demo
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档