Guava CaChe

Guava CaChe是本地(进程内)缓存

引包

1
2
3
4
5
<dependency>  
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>

Cache接口及其实现

1
2
3
4
5
6
7
8
9
10
Cache<k, v> cache = CacheBuilder.newBuilder()  
//设置cache的初始大小为10,要合理设置该值
.initialCapacity(10)
//设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操作
.concurrencyLevel(5)
//设置cache中的数据在写入之后的存活时间为10秒
.expireAfterWrite(10, TimeUnit.SECONDS)
//构建cache实例
.....
.build();

接口Cache是泛型,很好的支持了不同类型的key和value
TimeUnit.SECONDS 存活时间单位为秒
TimeUnit.HOURSC 存活时间单位为小时
TimeUnit.DAYS 存活时间单位为天

例如:

1
2
3
4
5
6
7
8
LoadingCache<Key, Object> cache= CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Object>() {
public Object load(Key key) throws AnyException {
return getObject(key);
}
});

Cache提供的常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/** 
* 该接口的实现被认为是线程安全的,即可在多线程中调用
* 通过被定义单例使用
*/
public interface Cache<K, V> {

/**
* 通过key获取缓存中的value,若不存在直接返回null
*/
V getIfPresent(Object key);

/**
* 通过key获取缓存中的value,若不存在就通过valueLoader来加载该value
* 整个过程为 "if cached, return; otherwise create, cache and return"
* 注意valueLoader要么返回非null值,要么抛出异常,绝对不能返回null
*/
V get(K key, Callable<? extends V> valueLoader) throws ExecutionException;

/**
* 添加缓存,若key存在,就覆盖旧值
*/
void put(K key, V value);

/**
* 删除该key关联的缓存
*/
void invalidate(Object key);

/**
* 删除所有缓存
*/
void invalidateAll();

/**
* 执行一些维护操作,包括清理缓存
*/
void cleanUp();
}

清除缓存

基于存活时间的清除

这应该是最常用的清除策略,在构建Cache实例的时候,CacheBuilder提供两种基于存活时间的构建方法:
(1)expireAfterAccess(long, TimeUnit):缓存项在创建后,在给定时间内没有被读/写访问,则清除。
(2)expireAfterWrite(long, TimeUnit):缓存项在创建后,在给定时间内没有被写访问(创建或覆盖),则清除。expireAfterWrite()方法有些类似于redis中的expire命令,但显然它只能设置所有缓存都具有相同的存活时间。

基于容量的清除

在构建Cache实例的时候,通过CacheBuilder.maximumSize(long)方法可以设置Cache的最大容量数,当缓存数量达到或接近该最大值时,Cache将清除掉那些最近最少使用的缓存。
以上是这种方式是以缓存的“数量”作为容量的计算方式,还有另外一种基于“权重”的计算方式。比如每一项缓存所占据的内存空间大小都不一样,可以看作它们有不同的“权重”(weights)。你可以使用CacheBuilder.weigher(Weigher)指定一个权重函数,并且用CacheBuilder.maximumWeight(long)指定最大总重

显式清除

任何时候,都可以显式地清除缓存项,而不是等到它被回收,Cache接口提供了如下API:
(1)个别清除:Cache.invalidate(key)
(2)批量清除:Cache.invalidateAll(keys)
(3)清除所有缓存项:Cache.invalidateAll()

基于引用的清除

在构建Cache实例过程中,通过设置使用弱引用的键、或弱引用的值、或软引用的值,从而使JVM在GC时顺带实现缓存的清除,不过一般不轻易使用这个特性。
(1)CacheBuilder.weakKeys():使用弱引用存储键
(2)CacheBuilder.weakValues():使用弱引用存储值
(3)CacheBuilder.softValues():使用软引用存储值

分享到: