guava里面如何实现缓存
来源:互联网 发布:cae软件 nvh 编辑:程序博客网 时间:2024/06/13 20:38
我们经常会遇到一些本地缓存的场景,比如遍历N条记录,依据记录里面的某个ID,获取到相应的名称,如果遍布的时候逐条去调用外部依赖的服务查询名称,显然会比较慢,如果把获取到的记录保存到本地的缓存里面,先判断本地缓存里面是否有记录存在,如果能够找到记录则直接取本地的数据。显然这样处理的话效率会提升不少。
相对于ConcurrentMap来讲guava cache适用于:
- 你愿意消耗一些内存空间来提升速度
- 你预料到某些键会被查询一次以上
- 缓存中存放的数据总量不会超出内存容量。本地单机缓存不是集中式缓存服务器。
只要你的场景符合其中的一项,那guava cache就适合你。
加载
“获取缓存--如果没有--则计算”【get - if - absent - compute】原子语义
在调用get时传入一个Callable实例。缓存元素也可以通过Cache.put方法直接插入,但自动加载是首选。因为它更容易推断所有缓存内容的一致性。
CacheLoader
LoadingCache是附带CacheLoader构建而成的缓存实现。创建自己的CacheLoader通常只需要简单地实现V load(K key) throws Exception方法。
从LoadingCache查询的正规方式是使用get(K)方法。这个方法要么返回已经缓存的值,要么使用CacheLoader向缓存原子地加载新值。
由于CacheLoader可能抛出异常,LoadingCache.get(K)也声明为抛出ExecutionExceptino异常。
如下:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() .maximumSize(1000) .build( new CacheLoader<Key, Graph>() { public Graph load(Key key) throws AnyException { // 手工抛异常 return createExpensiveGraph(key); } });...try {
// 也需要在get的时候抛出异常
return graphs.get(key);} catch (ExecutionException e) { throw new OtherException(e.getCause());}
如果你定义的CacheLoader没有声明任何检查异常,则可以通过getUnchecked(K)查找缓存;但必须注意,一旦CacheLoader声明了检查型异常,就不可以调用getUnchecked(K).
如下:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() .expireAfterAccess(10, TimeUnit.MINUTES) .build( new CacheLoader<Key, Graph>() { public Graph load(Key key) { // no checked exception return createExpensiveGraph(key); } });...return graphs.getUnchecked(key);
所有类型的guava cache,不管有没有自动加载功能都支持get(K,Callable(V))方法。这个方法返回缓存中相应的值,或者用给定的Callable运算并把结果加入到缓存中。
在整个加载方法完成前,缓存项相关的可观察状态都不会更改。这个方法实现了这个模式:如果有缓存则返回;否则运算、缓存、然后返回。
public static void main(String[] args) { String key = "instance_id"; Cache<String,Double> cache = CacheBuilder.newBuilder().maximumSize(1000).build(); int i = 1; while (i < 5){ i++; try { Double value = cache.get(key, new Callable<Double>() { @Override public Double call() throws Exception { System.out.println("hello"); //第一次没有的时候会运算然后添加到缓存里面。后面就直接从缓存里面读取数据. return 120d; } }); System.out.println(value); } catch (ExecutionException ex) { System.out.println(ex.getCause()); } } }
输出:
hello120.0120.0120.0120.0
相对于像Cache.asMap().putIfAbsent(K,V)来讲,Cache.get(K,Callable<V>)应该最优先使用。
缓存回收机制
提供了三种回收方式:基于容量回收、定时回收、基于引用回收
基于容量回收
需要使用CacheBuilder.maximumSize(long).
显式清除
个别清除:Cache.invalidate(key)
批量清除:Cache.invalidateAll(keys)
清除所有缓存项:Cache.invalidateAll()
在JDK8里面的实现代码
static Map<String, String> cache2 = new ConcurrentHashMap<>(); public static String getAppProduct(String appName){ // call aone System.out.println("call aone"); return "hello1"; } public static void main(String[] args) { String key = "instance_id"; String result = cache2.computeIfAbsent(key,(item) -> getAppProduct(key)); System.out.println(result);
其实我觉得用jdk8的这种方式也是可以的.
阅读全文
0 0
- guava里面如何实现缓存
- guava实现本地缓存
- guava缓存底层实现
- guava实现内存缓存
- Guava cache实现本地缓存
- Guava Cache实现本地缓存
- 如何使用Guava的缓存管理
- 如何使用Guava的缓存管理
- 如何使用Guava的缓存管理
- 使用google guava 实现定时缓存功能
- 使用google guava 实现定时缓存功能
- 使用google guava 实现定时缓存功能
- 使用Google Guava实现定时缓存功能
- Google Guava缓存实现接口的限流
- Google Guava 缓存实现接口的限流
- 本地缓存实现之Guava Cache
- Guava---缓存
- guava缓存
- 温故篇之素数
- 一起厌恶学习艳课网(一)
- caffe+VS2013+Windows无GPU快速配置教程
- SQL四种语言:DDL,DML,DCL,TCL
- OLAP引擎——Kylin介绍1
- guava里面如何实现缓存
- 第十九周:课后习题8.8
- 我的第一篇博客--MySQL登录密码修改
- Linux基础—/sbin/nologin与/bin/false的对比
- OLAP引擎——Kylin介绍2
- 常用meta标签整理
- FLV-Script Tag
- 正则表达式
- 2017 计蒜之道 初赛 百度的年会游戏(模拟)