前几天写过一篇博客:《java:基于弱引用(WeakReference)的FunctionCached实现》介绍在guava 缓存机制上实在基于弱引用(WeakReference)的缓存机制。
当时还挺得意,然而在我因为其他原因又进一步看了guava 缓存机制相关的代码后,才知道guava 缓存机制本身就支持弱引用(WeakReference)模式,还非常方便,根本不需要再发明一遍轮子。唉,这走的弯路又是吃了不看文档的亏。
com.google.common.cache.CacheBuilder.weakValues()
方法就是在构建一个缓存实例时指定弱引用(WeakReference)模式,以下是方法简要说明:
指定存储在缓存中的每个值(而不是键)都应封装在WeakReference中(默认情况下,使用强引用)。
弱值一旦是弱可访问的,就会被垃圾收集。
java
/**
* Specifies that each value (not key) stored in the cache should be wrapped in a
* {@link WeakReference} (by default, strong references are used).
*
* <p>Weak values will be garbage collected once they are weakly reachable. This makes them a poor
* candidate for caching; consider {@link #softValues} instead.
*
* <p><b>Note:</b> when this method is used, the resulting cache will use identity ({@code ==})
* comparison to determine equality of values.
*
* <p>Entries with values that have been garbage collected may be counted in {@link Cache#size},
* but will never be visible to read or write operations; such entries are cleaned up as part of
* the routine maintenance described in the class javadoc.
*
* @return this {@code CacheBuilder} instance (for chaining)
* @throws IllegalStateException if the value strength was already set
*/
@GwtIncompatible // java.lang.ref.WeakReference
public CacheBuilder<K, V> weakValues() {
return setValueStrength(Strength.WEAK);
}
所以要创建弱引用(WeakReference)模式的缓存对象就很简单:
java
@Test
public void test2() {
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder()
/** 指定值存储使用弱引用(WeakReference)模式 */
.weakValues()
.build(new CacheLoader<String, Integer>(){
@Override
public Integer load(String key) throws Exception {
/** 只会输出一次 */
System.out.printf("parse:%s", key);
return Integer.parseInt(key);
}});
cache.getUnchecked("3333");
cache.getUnchecked("3333");
cache.getUnchecked("3333");
}
CacheBuilder
不仅支持弱引用模式,还支持软引用(SoftReference),即softValues()
方法
进一步,guava缓存机制的键存储也支持弱引用和软引用模式(对应CacheBuilder
的weakKeys()
和softKeys()
方法)
更多说明参见guava的WIKI(https://github.com/google/guava/wiki)或源码。