guava中的Cache

本文深入探讨Guava Cache的使用场景及实现方式,包括如何通过CacheBuilder构建缓存,LoadingCache的自动加载特性,以及缓存的回收策略如基于大小、时间和引用的回收。同时介绍了如何进行批量操作和明确失效操作,以及RemovalListeners的使用。

Caches在很多情况下非常有用,比如,当一个值在计算和获取时很消耗时间

就可以通过caches来解决,你需要在特定的地方多次使用它。

Cache像一个ConcurrentMap,但不是完全相同,最不同的地方时ConcurrentMap

持久化所有加入的元素,直到明确被移除

而cache在到达内存限制时,自动回收对象。在一些情况下LoadingCache自动加载缓存,使得其更有用

 

Guava很有用:

1 使用内存加速

2. 一些值需要多次使用

3.适合数据只保存内存中使用(不适合数据太多)

 

通过CacheBuilder去获取一个Cache

LoadingCache

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

}

}

);

 

...

try{

return graphs.get(key);

}catch(ExecutionException e){

throw new OtherException(e.getCause());

}

 

同时支持批量的操作,CacheLoader.getAll()

 

通过Callable<V>获取,支持get(K,Callable<V>),这个方法返回和key相关的值

如果缓存中存在这样的值,返回,不存在则创建,加入缓存,并返回值

 

Cache<Key, Value> cache = CacheBuilder.newBuilder().maximumSize(1000)

.build();

try {

cache.get(key, new Callable<Value>) () {

@Override

public Value call () throws AnyException {

return doThingsTheHardWay(key);

}

});

} catch (ExecutionException e) {

throw new OtherException(e.getCause());

}

 

 

直接插入操作

 

通过cache.put(key,value)将值直接放入缓存,这样覆盖了以前缓存中

存在的相关值

 

收回

现实是我们没有足够的内存存储所有的值,我们需要考虑

什么情况下没有必要继续存储这个值,guava cache中提供了三种回收方法

基于大小

使用方法CacheBuilder.maxinumSize(long)设置缓存最大的限制

如果超过了限制,将会回收不经常使用的数据

 

 

基于时间

 

CacheBuilder提供了两种基于时间方法

expireAfterAccess(long,TimeUnit) 在指定时间内实体没有被访问或者修改,将会被回收

保证小于指定的缓存大小限制

expireAfterwrite(long,TimeUnit) 在指定时间内实体没有被创建或者值没有被替换

基于引用

 

guava允许设置缓存允许垃圾回收,使用在key或者values上弱引用

使用在值上软引用

 

CacheBuilder.weakKeys() s使用弱引用存储keys,这样实体允许在没有强或弱引用的时候垃圾回收;

CacheBuilder.weakBValues()使用弱引用存储值values,这样在没有强或者弱引用的情况下,进行垃圾回收

CacheBuilder.softValues() 使用软引用包装数据,软引用对象通过最近最少使用算法进行垃圾回收

 

 

明确迁移

在任何时候,都是明确失效而不是等待实体被回收

Removal Listeners

可以指定实体移除时候的特定的移除监听器

CacheBuilder.removalListener(RemovalListener)

 

 

/**

* 创建缓存

* @return

*/

public Cache<String, String> getCache() {

CacheLoader<String, String> loader = new CacheLoader<String, String>() {

 

@Override

public String load(String s) throws Exception {

return null;

}

};

RemovalListener<String, String> removalListener = new RemovalListener<String, String>() {

 

@Override

public void onRemoval(RemovalNotification<String, String> removalNotification) {

System.out.println("remove info ...");

}

};

return CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.MINUTES)

.removalListener(removalListener)

.build(loader);

}

 

 

 

转载于:https://my.oschina.net/iioschina/blog/2991556

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值