适用性:

计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。

常用用法:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});

项目中用法:

private LoadingCache<QueryEptAdsInfoVo, String> eptAdsInfoCache =CacheBuilder.newBuilder().softValues().maximumSize(5000).expireAfterWrite(1,TimeUnit.MINUTES)
.build(new CacheLoader<QueryEptAdsInfoVo,String>() {
@Override
public String load(final QueryEptAdsInfoVo tmp) throws Exception {
  //代码逻辑
}
});

之前常用 ConcurrentMap来做缓存,那它们有什么区别呢?

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

三种基于时间的清理或刷新缓存数据的方式:
expireAfterAccess: 当缓存项在指定的时间段内没有被读或写就会被回收。
expireAfterWrite:当缓存项在指定的时间段内没有更新就会被回收。
refreshAfterWrite:当缓存项上一次更新操作之后的多久会被刷新。
 
考虑到时效性,我们可以使用expireAfterWrite,使每次更新之后的指定时间让缓存失效,然后重新加载缓存。guava cache会严格限制只有1个加载操作,这样会很好地防止缓存失效的瞬间大量请求穿透到后端引起雪崩效应。
     然而,通过分析源码,guava cache在限制只有1个加载操作时进行加锁,其他请求必须阻塞等待这个加载操作完成;而且,在加载完成之后,其他请求的线程会逐一获得锁,去判断是否已被加载完成,每个线程必须轮流地走一个“”获得锁,获得值,释放锁“”的过程,这样性能会有一些损耗。这里由于我们计划本地缓存1秒,所以频繁的过期和加载,锁等待等过程会让性能有较大的损耗。
 
     因此我们考虑使用refreshAfterWrite。refreshAfterWrite的特点是,在refresh的过程中,严格限制只有1个重新加载操作,而其他查询先返回旧值,这样有效地可以减少等待和锁争用,所以refreshAfterWrite会比expireAfterWrite性能好。但是它也有一个缺点,因为到达指定时间后,它不能严格保证所有的查询都获取到新值。了解过guava cache的定时失效(或刷新)原来的同学都知道,guava cache并没使用额外的线程去做定时清理和加载的功能,而是依赖于查询请求。在查询的时候去比对上次更新的时间,如超过指定时间则进行加载或刷新。所以,如果使用refreshAfterWrite,在吞吐量很低的情况下,如很长一段时间内没有查询之后,发生的查询有可能会得到一个旧值(这个旧值可能来自于很长时间之前),这将会引发问题。
 
     可以看出refreshAfterWrite和expireAfterWrite两种方式各有优缺点,各有使用场景。那么能否在refreshAfterWrite和expireAfterWrite找到一个折中?比如说控制缓存每1s进行refresh,如果超过2s没有访问,那么则让缓存失效,下次访问时不会得到旧值,而是必须得待新值加载。由于guava官方文档没有给出一个详细的解释,查阅一些网上资料也没有得到答案,因此只能对源码进行分析,寻找答案。经过分析,当同时使用两者的时候,可以达到预想的效果,这真是一个好消息呐!
 
Guava Cache是单个应用运行时的本地缓存,单机版的缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试Memcached或Redis

google的CacheBuilder缓存的更多相关文章

  1. Java本地缓存解决方案其一(使用Google的CacheBuilder)

    前不久,业务实现上需要用到本地缓存来解决一些数据量相对较小但是频繁访问的数据,通过查找各种资料,找到了一种可以实现的方案--采用的是Google的CacheBuilder.下面是代码实现过程:1.首先 ...

  2. google guava cache缓存基本使用讲解

    代码地址:https://github.com/vikde/demo-guava-cache 一.简介 guava cache是google guava中的一个内存缓存模块,用于将数据缓存到JVM内存 ...

  3. spring中添加google的guava缓存(demo)

    1.pom文件中配置 <dependencies> <dependency> <groupId>org.springframework</groupId> ...

  4. Java内存缓存-通过Google Guava创建缓存

    谷歌Guava缓存 Guava介绍 Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中.实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问. Guava ...

  5. [Google Guava]学习--缓存cache

    适用性 缓存在很多情况下非常实用.例如,计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存. Guava Cache与ConcurrentMap很相似,但也不完全 ...

  6. google浏览器清除缓存

    google浏览器设置不缓存的方法 摘要:我们在做web开发的时候特别是在调试js时,会经常使用的google浏览器,这个时候就要我们修改过的代码可能不能生效.这是因为我们的浏览器默认是有缓存的,但是 ...

  7. 设置Google浏览器不缓存JS

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  8. Google浏览器清除缓存快捷键

    1.CTRL+SHIFT+DEL:直接进入“清除浏览数据”页面,包括清除浏览历史记录.清空缓存.删除Cookie等. 2.chrome浏览器F12中 ctrl+p 可以定位文件

  9. 同时使用Redis缓存和Google Guava本地缓存注意事项(深拷贝和浅拷贝)

    目录 1.问题场景及说明 2.Redis 缓存是深拷贝 3.Guava本地缓存直接获取则是浅拷贝 4.如何实现Guava获取本地缓存是深拷贝? 1.问题场景及说明 系统中同时使用 Redis 缓存和 ...

随机推荐

  1. golang实现四种排序(快速,冒泡,插入,选择)

    本文系转载 原文地址: http://www.limerence2017.com/2019/06/29/golang07/ 前面已经介绍golang基本的语法和容器了,这一篇文章用golang实现四种 ...

  2. oslo_db.sqlalchemy.engines连库

    _ mysql -uroot -pc1234 oslo_db.sqlalchemy.engines root@devstack2019:/etc/keystone# more keystone.con ...

  3. 微信小程序页面左右滑动事件

    微信小程序提供了页面的上下滚动的事件,在页面的js文件中, page({ onPageScroll(e) { console.log(e.scrollTop) } }) 但是不是滑动事件,滑动事件需要 ...

  4. CTF攻防练习之综合训练1

    主机:192.168.32.152 靶机:192.168.32.166 首先使用nmap,nikto -host ,dirb扫描,探测靶场开放了 21,22,80d端口已经发现有一下关键信息 进入lo ...

  5. C# Job System概述

    C# 作业系统是如何工作 允许用户编写与Unity其余部分良好交互的多线程代码,并使编写正确的代码变得更加容易. 编写多线程代码可以提供高性能的好处,其中包括帧速率的显著提高.以及将Burst编译器与 ...

  6. PI膜概述

    一.概述 1.简述 聚酞亚胺薄膜又称PI薄膜(polyimide filin)是一种含有酞亚胺或丁二酞亚胺的绝缘类高分子材料.是目前工程塑料中耐热性最好的品种之一. 2.发展简史 1908年,PI聚合 ...

  7. xgboost的使用

    1.首先导入包 import xgboost as xgb 2.使用以下的函数实现交叉验证训练xgboost. bst_cvl = xgb.cv(xgb_params, dtrain, num_boo ...

  8. NOIp2013D2T3 华容道【搜索&图论-最短路】

    题目传送门 暴力搜索 看到这道题的第一反应就是直接上$bfs$啦,也没有想到什么更加优秀的算法. 然后就是$15$分钟打了$70$分,有点震惊,纯暴力诶,这么多白给分嘛,太划算了,这可是$D2T3$诶 ...

  9. MSF魔鬼训练营-5.3 MS08-067安全漏洞实战

    msf > search ms08_067 Matching Modules ================    Name                                 D ...

  10. Spring(十三)-- Spring 事务

    Spring 事务 1. 回忆之前事务知识点  一:事务的概念 将一系列的数据操作捆绑在一起,成为一个整体进行统一管理! 一条或者多条sql语句的集合!  二:事务的ACID特性 原子性(Atomic ...