缓存是日常开发中经常应用到的一种技术手段,合理的利用缓存可以极大的改善应用程序的性能。
Guava官方对Cache的描述
Caches are tremendously useful in a wide variety of use cases. For example, you should consider using caches when a value is expensive to compute or retrieve, and you will need its value on a certain input more than once.
A Cache is similar to ConcurrentMap, but not quite the same. The most fundamental difference is that a ConcurrentMap persists all elements that are added to it until they are explicitly removed. A Cache on the other hand is generally configured to evict entries automatically, in order to constrain its memory footprint. In some cases a LoadingCache can be useful even if it doesn’t evict entries, due to its automatic cache loading.
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
<version>18.0version>
dependency>
Guava Cache有以下两种创建方式:
LoadingCache graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
然后,我们可以通过 V LoadingCache.get(K key) 方法来获取cache
try {
return graphs.get(key);
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
也可以不处理异常
return graphs.getUnchecked(key);
Cache cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.build();
然后通过Cache.get(String arg0, Callable
try {
// If the key wasn't in the "easy to compute" group, we need to
// do things the hard way.
cache.get(key, new Callable() {
@Override
public Value call() throws AnyException {
return doThingsTheHardWay(key);
}
});
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
使用cache.put(key, value)方法可以直接向缓存中插入值,这会直接覆盖掉给定键之前映射的值。
例如:
cache.put(key, value)
1、基于大小
通过CacheBuilder.maximumSize(long)指定缓存容量大小,如下:
LoadingCache graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(
new CacheLoader() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
另外,如果缓存值占据完全不同的内存空间,可以使用CacheBuilder.maximumWeight(long)指定最大总重,如下:
LoadingCache graphs = CacheBuilder.newBuilder()
.maximumWeight(100000)
.weigher(new Weigher() {
public int weigh(Key k, Graph g) {
return g.vertices().size();
}
})
.build(
new CacheLoader() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
2、基于时间
CacheBuilder provides two approaches to timed eviction:
例如:
LoadingCache graphs = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(
new CacheLoader() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
At any time, you may explicitly invalidate cache entries rather than waiting for entries to be evicted. This can be done:
Guava User Guide:https://github.com/google/guava/wiki
http://ifeve.com/google-guava-cachesexplained/