Guava学习笔记(三)

Guava学习笔记(三)

以前我也没想过使用堆缓存或者使用堆外缓存,如果这对你是个知识盲区?

Guava Cache网上一搜有很多的教程,阐述了它的各种用法,我只是想将这些Guava Cache的知识压缩一下,连成一条线,轻松的记住。

场景

由于它是JVM内存级别的缓存,特点就是快,缺点嘛也多,内存有限,垃圾回收问题,分布式问题等等。

适合存放少量,高频访问的数据。

使用

存与读

创建一个Cache容器

1
2
3
4
5
6
7
private Cache<String, User> cache = CacheBuilder.newBuilder()
.build(new CacheLoader<String, User>() {
@Override
public User load(String key) throws Exception {
return null;
}
});

想容器中存储数据

1
cache.put("apple", new User("apple", 1));

从Cache中读取数据

1
2
3
4
public void test1() {
User u = cache.getIfPresent("apple");
assertEquals(1, u.getAge());
}

刷新

之前在看亿级流量那本书里面提到了缓存用法中,有一种用法是Read-Through,意思是获取数据时,直接请求缓存,如果命中缓存则从缓存中返回,否则回源的数据源地址查询。

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
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(
@Override
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return getGraphFromDatabase(key);
}
@Override
public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
if (neverNeedsRefresh(key)) {
return Futures.immediateFuture(prevGraph);
} else {
// asynchronous!
ListenableFutureTask<Graph> task = ListenableFutureTask.create(new Callable<Graph>() {
public Graph call() {
return getGraphFromDatabase(key);
}
});
executor.execute(task);
return task;
}
}
});

这个是文档中给出的示例,就是采用这种Read-Through的方法使用缓存

上述的代码指定了刷新的时间每分钟,刷新没成功前,会返回旧值。

清理

Guava提供了多种清理策略

大小

这个大小还需要自己算–

1
2
3
4
5
6
7
8
9
10
11
12
13
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumWeight(100000)
.weigher(new Weigher<Key, Graph>() {
public int weigh(Key k, Graph g) {
return g.vertices().size();
}
})
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});

数量

按照缓存key数量 .maximumSize(3)

最近使用

expireAfterAccess(long, TimeUnit)

最近写时间

expireAfterWrite(long, TimeUnit)

垃圾回收器清理

通过设置K和V为弱引用的方法,让垃圾回收器进行回收

  • CacheBuilder.weakKeys()
  • CacheBuilder.weakValues()
  • CacheBuilder.softValues() 软引用: 我也没懂

手动清理

  • Cache.invalidate(key)
  • Cache.invalidateAll(keys)
  • Cache.invalidateAll()

最后,可以添加Remove监听来收到数据清理时的通知

1
2
3
4
CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.removalListener(removalListener)
.build(loader);

统计

打开统计

1
CacheBuilder.recordStats()

获得统计数据

1
CacheStats cacheStats = cache.stats();

参考

1. 官方文档
2. 中文翻译
3. Guava Cache用法介绍

# guava

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×