1.是什么?
guava cache是本地缓存实现得一种方式。
guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也是很有用的,因为它会自动加载缓存。
优点:可以按照一定的规则淘汰数据
清除数据时的回调通知
并发处理能力
2.缓存回收?
Guava Cache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。
基于容量回收?
如果要规定缓存项的数目不超过固定值,只需使用maximumSize(long)。缓存将尝试回收最近没有使用或总体上很少使用的缓存项。利用了LRU算法进行回收。
定时回收?
CacheBuilder提供两种定时回收的方法:
-
expireAfterAccess(30, TimeUnit.MINUTES ) // 30min内没有被读或写就会被回收 ;
expireAfterWrite(30, TimeUnit.MINUTES ) // 30min内没有没有更新就会被回收 :
refreshAfterAccess(30, TimeUnit.MINUTES) //上一次更新操作30min后再刷新;
此两种回收是如何做到得?是通过队列做到得,一个access队列,有一个write队列。遍历队列就可以进行回收。
expire 在load 阶段——同步机制:当前线程load未完成,其他线程呈阻塞状态,待当前线程load完成,其他线程均需进行”获得锁--获得值--释放锁“的过程。这种方法会让性能有一定的损耗。
refresh 在load阶段——异步机制 :当前线程load未完成,其他线程仍可以取原来的值,等当前线程load完成后,下次某线程再取值时,会判断系统时间间隔是否时超过设定refresh时间,来决定是否设定新值。所以,refresh机制的特点是,设定30分钟刷新,30min后并不一定就是立马就能保证取到新值。
基于引用回收?
主要是和java得几种引用有关,java提供了4种引用:
强引用:通常情况下,Object obj = new Object() 就是一种强引用得方式,垃圾回收得时候进行回收。
弱引用:这种是使用过之后就进行回收,例子:ThreadLocal
软引用:这种方式是当jvm空间满了就进行回收。
虚引用:虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
guava cache是支持支持引用设置得,可以配置其参数:
weakKeys() 弱引用key
weakValues() 弱引用value
softValues()软引用value,不支持key得软引用设置。
3.并发
concurrencyLevel(int conSum) 并发树操作,允许多少并发进行加载load。
4.总结
public static LoadingCache<String, List<String>> testCache = CacheBuilder.newBuilder()
//设置缓存初始大小,应该合理设置,后续会扩容
.initialCapacity(10)
//最大值
.maximumSize(100)
//并发数设置
.concurrencyLevel(5)
//缓存过期时间,写入后10分钟过期
.expireAfterWrite(600, TimeUnit.SECONDS)
// 此缓存对象经过多少秒没有被访问则过期。
.expireAfterAccess(10,TimeUnit.SECONDS)
//弱引用value
.weakValues()
//弱引用key
.weakKeys()
//软引用value
.softValues()
//统计缓存命中率,可以输出命中率
.recordStats()
.build(new CacheLoader());
public static class CacheLoader extends CacheLoader<String, List<String>> {
@Override
public List<String> load(String key) {
System.out.println("加载开始");
List<String> list = new ArrayList<>();
System.out.println("加载数据结束");
return list;
}
}