1、简介
线程安全
Guava Cache提供了一种把数据(key-value对)缓存到本地(JVM)内存中的机制,适用于很少会改动的数据,比如地区信息、系统配置、字典数据,等。
Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素。
2、加载数据的两种方式
CacheLoader:在build cache的时候定义一个CacheLoader来获取数据,适用的情况:有固定的方式可以根据key来加载或计算value的值,比如从数据库中获取数据
Callable:在get的时候传入一个Callable对象,适用的情况:如果从缓存中获取不到数据,则另外计算一个出来,并把计算结果加入到缓存中
3、缓存回收方式
(1)基于容量的回收(size-based eviction),有两种方式,接近最大的size或weight时回收:
基于maximumSize(long):一个数据项占用一个size单位,适用于value是固定大小的情况
基于maximumWeight(long):对不同的数据项计算weight,适用于value不定大小的情况,比如value为Map类型时,可以把map.size()作为weight
(2)定时回收(Timed Eviction):
expireAfterAccess(long, TimeUnit):缓存项在给定时间内没有被读/写,则回收。
expireAfterWrite(long, TimeUnit):缓存项在给定时间内没有被写访问(创建或覆盖),则回收。
(3)基于引用的回收(Reference-based Eviction),通过使用弱引用的键或值、或软引用的值,把缓存设置为允许垃圾回收器回收:
CacheBuilder.weakKeys():使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被GC回收
CacheBuilder.weakValues():使用弱引用存储值。当值没有其它(强或软)引用时,缓存项可以被GC回收
CacheBuilder.softValues():使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。影响性能,不推荐使用。
(4)显式清除(invalidate)
个别清除:Cache.invalidate(key)
批量清除:Cache.invalidateAll(keys)
清除所有缓存项:Cache.invalidateAll()
4、创建方式
private Cache<K, V> cache=
CacheBuilder
.newBuilder()
.maximumSize(2)
.expireAfterWrite(10, TimeUnit.MINUTES).build();
CacheBuilder.newBuilder()后面能带一些设置回收的方法:
(1)maximumSize(long):设置容量大小,超过就开始回收。
(2)expireAfterAccess(long, TimeUnit):在这个时间段内没有被读/写访问,就会被回收。
(3)expireAfterWrite(long, TimeUnit):在这个时间段内没有被写访问,就会被回收 。
(4)removalListener(RemovalListener):监听事件,在元素被删除时,进行监听。
5、常用方法
V getIfPresent(Object key) 获取缓存中key对应的value,如果缓存没命中,返回null。return value if cached, otherwise return null.
V get(K key) throws ExecutionException 获取key对应的value,若缓存中没有,则调用LocalCache的load方法,从数据源中加载,并缓存。 return value if cached, otherwise load, cache and return.
void put(K key, V value) if cached, return; otherwise create, cache , and return.
void invalidate(Object key); 删除缓存
void invalidateAll(); 清除所有的缓存,相当于map的clear操作。
long size(); 获取缓存中元素的大概个数。为什么是大概呢?元素失效之时,并不会实时的更新size,所以这里的size可能会包含失效元素。
CacheStats stats(); 缓存的状态数据,包括(未)命中个数,加载成功/失败个数,总共加载时间,删除个数等。
ConcurrentMap
批量操作就是循环调用上面对应的方法,如:
ImmutableMap
void putAll(Map<? extends K,? extends V> m);
void invalidateAll(Iterable<?> keys);