缓冲管理器分类使用说明

Guava缓冲管理器分类使用说明

【模板】:

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);
		}
	});

【用于】:

计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。(1)愿意消耗一些内存空间来提升速度;(2)预料到某些键会被查询一次以上;(3)缓存中存放的数据总量不会超出内存容量。(Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试Memcached这类工具)

【加载】: 

为保证缓存内容的一致性,应该在调用get时传入一个Callable实例,保留“获取缓存-如果没有-则计算[get-if-absent-compute]”的原子语义。

【From a CacheLoader

【方式一】:LoadingCache.get(K)声明为抛出ExecutionException异常  注意:声明异常不能使用getUnchecked(K)查找缓存

LoadingCache是附带CacheLoader构建而成的缓存实现,创建自己的CacheLoader通常只需要简单地实现V load(K key) throws Exception方法(这个方法要么返回已缓存的值,要么使用CacheLoade

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
	.maximumSize(1000)
	.build(
		new CacheLoader<Key, Graph>() {
			public Graph load(Key key) throws AnyException {
				return createExpensiveGraph(key);
		   }
		}); 
...
try {
    return graphs.get(key);
} catch (ExecutionException e) {
    throw new OtherException(e.getCause());
}

r向缓存原子地加载新值。)

【方式二】:定义的CacheLoader没有声明任何检查型异常 

  使用getUnchecked() 方法,如果对应值不存在,则计算并缓存值到缓存中, Tips : 批量查询可以使用getAll(Iterable<? extends K>)方法。

LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()  
    .expireAfterAccess(10,TimeUnit.MINUTES)  
    .build(  
        newCacheLoader<Key,Graph>(){  
            publicGraph load(Key key){// no checked exception  
                return createExpensiveGraph(key);  
            }  
        });  
  
...  
return graphs.getUnchecked(key); 
  • 【From a Callable】 所有Guava缓存,不论是否会自动加载,都支持get(K, Callable(V))方法

当给定键的缓存值已存在时则直接返回,否则通过指定的Callable方法进行计算并将值存放到缓存中。直到加载完成时,相应的缓存才会被更改。该方法简单实现了"if cached, return; otherwise create, cache and return"语义。

Cache<Key,Value> cache =CacheBuilder.newBuilder()  
    .maximumSize(1000)  
    .build();// look Ma, no CacheLoader  
...  
try{  
    // If the key wasn't in the "easy to compute" group, we need to  
    // do things the hard way.  
    cache.get(key,newCallable<Value>(){  
        @Override  
        publicValue call()throwsAnyException{  
            return doThingsTheHardWay(key);  
        }  
    });  
}catch(ExecutionException e){  
    thrownewOtherException(e.getCause());  
}

【注意】——> 当使用CacheLoader或Callable来加载缓存时,应该优先使用Cache.get(K, Callable<V>),而不是Cache.asMap().putIfAbsent (asMap中的任何方法都不能自动的将数据加载到缓存中)

【缓存回收】:  

 【缓存值不再值得保留】:(1)基于容量回收策略;(2)基于时间回收策略;(3)基于引用回收策略

基于容量回收策略

LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()  
    .maximumWeight(100000)  
    .weigher(  
        newWeigher<Key,Graph>(){  
            publicint weigh(Key k,Graph g){  
                return g.vertices().size();  
           }  
        })  
    .build(  
        newCacheLoader<Key,Graph>(){  
            publicGraph load(Key key){// no checked exception  
                return createExpensiveGraph(key);  
            }  
        });  

基于时间回收策略:(定时回收)

  CacheBuilder为基于时间的回收提供了两种方式:(定时过期回收会在写的过程中周期执行,偶尔也会读的过程中执行)

  • expireAfterAccess(long, TimeUnit) 当缓存项在指定的时间段内没有被读或写就会被回收。这种回收策略类似于基于容量回收策略;
  • expireAfterWrite(long, TimeUnit) 当缓存项在指定的时间段内没有更新就会被回收。如果我们认为缓存数据在一段时间后数据不再可用,那么可以使用该种策略。

 基于引用回收策略:(定时回收)

  • CacheBuilder.weakKeys() 使用弱引用存储键。当没有(强或软)引用到该键时,相应的缓存项将可以被垃圾回收。由于垃圾回收是依赖==进行判断,因此这样会导致整个缓存也会使用==来比较键的相等性,而不是使用equals();
  • CacheBuilder.weakValues() 使用弱引用存储缓存值。当没有(强或软)引用到该缓存项时,将可以被垃圾回收。由于垃圾回收是依赖==进行判断,因此这样会导致整个缓存也会使用==来比较缓存值的相等性,而不是使用equals();
  • CacheBuilder.softValues() 使用软引用存储缓存值。当响应需要时,软引用才会被垃圾回收通过最少使用原则回收掉。由于使用软引用造成性能上的影响,我们强烈建议使用可被预言的maximum cache size的策略来代替。同样使用softValues()缓存值的比较也是使用==,而不是equals()。

【移除监听器】

 【参考文献】:如何使用Guava的缓存管理

 【参考文献】:Guava 驱逐策略、弱引用键、缓存值软引用、刷新缓存、删除通知

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值