在工作中,加Cache是非常常见的一种性能优化手段,操作系统底层、计算机硬件层为了性能优化加了各种各样的Cache,当然大多数都是对应用层透明的。但如果你想在应用层加Cache的话,可能就需要你自己实现了。

  其实在Java环境下,Cache有各种各样的选择,比如最初级的你可以直接用HashMap实现一个Cache,不过你得自己关注下数据加载和淘汰的策略。更高级的有像spring-cache,代码都不需要改,只需要简单加几个注解就可以实现对关键数据的缓存,相当方便(后续我也会出一篇博客介绍下spring-cache)。 今天我们要介绍的是谷歌guava包中的LoadingCache, 也是功能完善,简单好用。

  LoadingCache是Guava包中提供一个一种本地Cache,本地Cache的优势就是没有网络IO,速度快。但劣势也很明显,Cache容量受限于本地内存大小,Cache中的数据没法共享。所以它就只适合少量热点数据的缓存,其使用方法也很简单,我们拿maven为例,你只需要添加一下Maven依赖即可引入guava包:

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

使用代码也非常简单,如下:

    private static LoadingCache<String, String> cache =CacheBuilder.newBuilder()// 初始化容量.initialCapacity(4)// 缓存池大小,在缓存数量到达该大小时, Guava开始回收旧的数据.maximumSize(8)// 设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程里面不定期维护).expireAfterAccess(5, TimeUnit.SECONDS)// 设置缓存在写入之后 设定时间 后失效.expireAfterWrite(5, TimeUnit.SECONDS)// 数据被移除时的监听器, 缓存项被移除时会触发执行.removalListener((RemovalListener<String, String>) rn -> {System.out.println(String.format("数据key:%s value:%s 因为%s被移除了", rn.getKey(), rn.getValue(),rn.getCause().name()));})// 开启Guava Cache的统计功能.recordStats()// 数据写入后被多久刷新一次.refreshAfterWrite(5, TimeUnit.SECONDS)// 数据并发级别.concurrencyLevel(16)// 当缓存中没有数据时的数据加载器.build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {return key + "_" + System.currentTimeMillis();}});

  然后我们就可以直接在代码的其他地方用cache.get("myKey") 来愉快地使用LoadingCache了,它会主动加载数据,并在存储空间不够或者数据过期时清理掉不需要的数据,非常省心且方便。

这里有些重点参数,下面详细介绍下:

参数 作用 注意事项
maximumSize 缓存的k-v最大数据,当总缓存的数据量达到或者快达到这个值时,就会淘汰它认为不太用的一份数据,近似LRU或者LFU策略 并不一定是达到这个值才开始淘汰旧数据,可能接近时就会开始淘汰
expireAfterAccess 数据被访问后多久就会过期,这个策略主要是为了淘汰长时间不被访问的数据 数据过期不是立即淘汰,而是有数据访问时才会触发
expireAfterWrite 数据写入后多久过期,这个策略是为了防止旧数据被缓存过久 同上
refreshAfterWrite 数据写入后多久刷新一次,这个类似于expireAfterWrite,但它会主动更新数据 同上
concurrencyLevel 数据的并发级别,LoadingCache为了实现线程安全,它里面采用了类似Java7中ConcurrentHashMap的实现,采用了分段加锁的方式,分段数影响了它的最大并发量
recordStats 开启Cache的状态统计(默认是开启的) 开启这个是会影响到性能的,如果要求极致性能的话关注下个

  我们来重点介绍下CacheLoader CacheStats和RemovalListener,因为这三者涉及到了数据的加载、使用和删除的完整生命周期,先来看下CacheLoader。

CacheLoader

  CacheLoader的作用就是为了在Cache中数据缺失时加载数据,其中最重要的方法就是load()方法,你可以在load() 方法中实现对应key加载数据的逻辑。在调用LoadingCache的get(key)方法时,如果key对应的value不存在,LoadingCache就会调起你在创建cache时传入的CacheLoader的load方法。

CacheStats

  使用CacheStats cacheStats = cache.stats(); 我就可以获取到cache的stats数据。从cacheStats中我们可以看到cache的命中率、命中数、异常率、加载时延……等数据,通过这些数据就可以直观地看出我们cache的一些性能指标,如果做出一些参数调整。 比如如果命中率过低,我们是不是可以调整大下maximumSize,或者调整下数据的过期策略?

RemovalListener

  RemovalListener会在LoadingCache中数据被清理时调起,其实就是个监听器模式,这样你可以通过Listener实现对数据淘汰事件的监听,比如在数据淘汰时打一行日志啥的。使用方法也很简单,在Java8+上你可以直接使用lambda表达式,或者也可以自己实现RemovalListener接口,并在构建Cache时注册进去即可。

public enum RemovalCause {EXPLICIT {@Overrideboolean wasEvicted() {return false;}},REPLACED {@Overrideboolean wasEvicted() {return false;}},COLLECTED {@Overrideboolean wasEvicted() {return true;}},EXPIRED {@Overrideboolean wasEvicted() {return true;}},SIZE {@Overrideboolean wasEvicted() {return true;}};abstract boolean wasEvicted();
}

  在RemovalListener内,我们可以通过RemovalListener获取到被删除的数据的key和value,也可以知晓数据被删除的原因。可以看到有个RemovalCause枚举类,详细说明了几种数据被清除的原因,比如被用户主动删除(RemovalCause.EXPLICIT),被替换(RemovalCause.REPLACED),过期淘汰(RemovalCause.EXPIRED),被GC收集器删除(RemovalCause.COLLECTED),容量不够导致的删除(RemovalCause.SIZE)。


   关于LoadingCache的介绍就到这了。再说下谷歌的guava包,其实guava是一个很好用的Java开源开发包,里面除了cache之外,还有各种集合工具、并发工具,Cache只是其中很小的一部分,后续有机会我们在详细探索下guava。今天的文章就到这了,大家觉得有用请点赞,喜欢请关注。

谷歌Guava LoadingCache介绍相关推荐

  1. [由零开始]Guava Cache介绍和用法

    Guava Cache介绍 Guava是Google提供的一套Java工具包,而Guava Cache是一套非常完善的本地缓存机制(JVM缓 存). Guava cache的设计来源于CurrentH ...

  2. spring boot 整合 谷歌guava的EventBus 实现单机版的消息发布订阅

    spring boot 整合 谷歌guava的EventBus 实现单机版的消息发布订阅 大型分布式系统,直接用mq解耦,那么单机系统怎么办,可以考虑用EventBus 用EventBus的好处也是异 ...

  3. 阿昌教你使用谷歌guava工具包---集合包

    前言 今天阿昌这里分享一个谷歌guava工具包,自己在工作业务中洋哥推荐的一个集合工具包的partition()方法,看了看这个工具包的方法并不是很多,主要常用也就是以下正文的3个方法. 准备 走开始 ...

  4. 谷歌Guava工具类的使用(1):BloomFilter的使用

    谷歌Guava工具类的使用(1):BloomFilter的使用 具体代码实现如下所示: // 创建布隆过滤器,设置存储的数据类型,预期数据量,误判率 (必须大于0,小于1) int insertion ...

  5. 爆料:谷歌金山词霸功能介绍及预览图

    5月8日上线的谷歌新产品,叫"金山词霸"还是"谷歌词霸"?正确答案是"谷歌金山词霸",这款新产品是在原金山词霸的基础上进行了一些互联网方面的 ...

  6. Guava Cache介绍

    1.缓存回顾: 使用场景:互联网,数据越来越多,用户越来越多,并发量.吞吐量越来越大 使用数据库存储,分库分表,也不能满足要求,使用缓存,减轻数据库的压力 临时存储的数据 其他的场景:Session分 ...

  7. 谷歌guava工具包详解

    概述 工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率.谷歌作为大公司,当然会从日常的工作中提取中很多高效率的方法出来.所以就诞生了guava. guava的优点: 高 ...

  8. 【guava】 谷歌guava工具包的常用方法 双key的map 、驼峰转下划线等小结

    文章目录 1. maven引入 (某些框架会引入guava 注意版本冲突问题) 2. guava 对集合的处理 3. guava的 双键table (双key map) 4. guava的文件读写 代 ...

  9. guava LoadingCache 的用法

    这段代码主要功能是实现使用guava的LoadingCache记录一个ip在一段时间类反复登录失败的次数,如果超过10次则在规定时间(expiration=1800)内禁止登录(Blocked);使用 ...

最新文章

  1. Nodejs Express dockerfile最佳实践
  2. XML 标签 首字母转换为大写
  3. 写给初学大数据的你,从零开始学习大数据开发的完整学习路线
  4. 软工作业 6:软件设计—— 用户体验(案例分析)
  5. python1~10阶乘while_Python3基础 while 阶乘
  6. Linux以及各大发行版介绍
  7. 木板最优切割利润最大_最多进行K笔交易的股票最大买卖利润
  8. greendao3.2.3配置时遇到的问题
  9. Android IntentService使用
  10. JUnit5 @AfterEach注解示例
  11. 随想录(为什么循环队列具有先天的并行性)
  12. 做游戏,学编程(C语言) 3 利用函数对飞机游戏进行重构
  13. android webdav 播放器,Android WebDAV
  14. 开课吧:OOM常见的解决方案有哪些?
  15. linux下飞信安装详细过程
  16. 头条 上传图片大小_遇到不会注册今日头条号,这么办?
  17. 华为云账号登录流程和方法
  18. 身份证男女识别---非线性问题01
  19. 怎样在拼打日语汉字时,在字上同时显示假名
  20. 闲逸游戏态度决定胜负,安全决定未来!

热门文章

  1. 30分钟(零成本)快速搭建markdown个人github博客
  2. Random(三)反射的高效替代方案,Unsafe类
  3. Facebook Surround360 学习笔记--(3)硬件设计要点
  4. 极品飞车无限狂飚连不上服务器,极品飞车无限狂飙连接不上 | 手游网游页游攻略大全...
  5. 旭元数艺:以科技创新的力量共度传统佳节
  6. 了解完水中油的危害,你便知道水中油检测仪的重要性有多大
  7. 集成docker jenkins github 发布运行
  8. 北京石景山中央空调维保,写字楼中央空调维保注意要点
  9. 2023OD机试---特殊赛制投篮大赛
  10. dts文件分析---以ov5640为例,修改dts文件使ov5640使用第二个IPU