Java向:CacheBuilder

≯℡__Kan透↙ 提交于 2019-11-26 10:13:30

JavaDoc

com.google.common.cache
Class CacheBuilder<K,V>
java.lang.Object
com.google.common.cache.CacheBuilder<K,V>
Type Parameters:
K - the base key type for all caches created by this builder
V - the base value type for all caches created by this builder

@GwtCompatible(emulated=true)
public final class CacheBuilder<K,V>
extends Object

其中,@GwtCompatible代表可以通过Google Web Toolkit使用。具体可以参考以下链接(https://guava.dev/releases/18.0/api/docs/com/google/common/annotations/GwtCompatible.html)。

 

在具体了解CacheBuilder之前,我们先了解其他两个class,即LoadingCache和Cache。

LoadingCache JavaDoc

@Beta
@GwtCompatible
public interface LoadingCache<K,V>
extends Cache<K,V>, Function<K,V>

@Beta的含义参考以下链接(https://guava.dev/releases/18.0/api/docs/com/google/common/annotations/Beta.html)。

  1. 一个具有半持久属性的键值对映射。值都是自动从缓存加载的,除非淘汰或人为移除否则它们一直存储在缓存中。
  2. 实现这个接口需要保证线程安全,并且可以被多个同一时刻的进程安全地access到。
LoadingCache Method
方法名称 返回
ConcurrentMap<K, V> asMap() 以一个线程安全的map模式返回存储在缓存中的键值对
V get(K key) 返回内存中与此键值相对应的value值。
ImmutableMap<K, V> getAll(Iterable<? extends K> keys) 返回输入的键值对应的value值。
getUnchecked(K key) 返回内存中与此键值相对应的value值。
void refresh(K key) 给键值为key的key加载一个新value,可能是异步的。

 

Cache JavaDoc

@Beta
@GwtCompatible
public interface Cache<K,V>
  1. 一个具有半持久属性的键值对映射。缓存中的键值对通过人为地使用get(Object, Callable) 或者 put(Object, Object)方法获取或者添加,除非淘汰或人为移除否则它们一直存储在缓存中。
  2. 实现这个接口需要保证线程安全,并且可以被多个同一时刻的进程安全地access到。

 

再回到CacheBuilder

LoadingCache和Cache的实例的builder拥有下列中至少一个feature:

  1. 自动从缓存中加载键值对
  2. 当缓存中达到了最大存储数量时,会首先从缓存中删除使用频数最少的那些键值对
  3. 对键值对进行基于时间维度的过期验证,具体时间从上次access或写入算起
  4. 键值都会自动用 weak reference(https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html?is-external=true) 进行包装
  5. value值会自动用weak reference或者soft reference进行包装
  6. 当键值对要淘汰时会提醒
  7. 可以对缓存的access统计量进行累积

以上这些features都是可选的,在创建缓存时可以选择其中任何一个或者几个,或者不选。默认情况下创建的CacheBuilder不会淘汰任何键值对。看一个例子,

private LoadingCache<String, Graph> graphs = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .removalListener(MY_LISTENER)
            .build(new CacheLoader<String, Graph>() {
                @Override
                public Graph load(String key) throws Exception {
                    return createExpensiveGraph(key);
                }
            });

或者你也可以这么玩,

// 通常情况下会从命令行或者配置文件中配置spec
String spec = "maximumSize=10000,expireAfterWrite=10m";
    LoadingCache<String, Graph> graphs = CacheBuilder.from(spec)
            .removalListener(MY_LISTENER)
            .build(new CacheLoader<String, Graph>() {
                @Override
                public Graph load(String key) throws Exception {
                    return createExpensiveGraph(key);
                }
            });

返回的缓存是一个同ConcurrentHashMap有相似属性的哈希表,并实现了LoadingCache和Cache接口的所有可选操作。其中asMap方法拥有的是weakly consistent iterators。这意味着,concurrent use是安全的,但如果迭代器创建之后有任何线程修改缓存的话,它不会抛出迭代器中发生的任何变化,比如ConcurrentModificationException

需要注意的是,默认情况下返回的缓存使用的是equals来确认键值或者value值的相等性的。但是如果你指定了weakKeys()或者,那么equals会被“==”替代。相似地情况也会发生在weakValues() 或 softValues()被指定的情况下。

maximumSizemaximumWeightexpireAfterWriteexpireAfterAccessweakKeysweakValues, 或 softValues中任意一个参数被指定时,键值对会自动根据对应的规则被淘汰。

设置参数 淘汰规则
maximumSize/maximumWeight 每次修改缓存的时候可能会引发淘汰
expireAfterWrite/expireAfterAccess 每次修改缓存或者加载缓存或Cache.cleanup()的时候,可以通过Cache.size()方法查看过期键值对的数量,但是针对读写操作的话过期键值对是不可见的。
weakKeysweakValuessoftValues 这一段直接复制粘贴,因为我还没弄清楚reference object(it is possible for a key or value present in the cache to be reclaimed by the garbage collector. Entries with reclaimed keys or values may be removed from the cache on each cache modification, on occasional cache accesses, or on calls to Cache.cleanUp(); such entries may be counted in Cache.size(), but will never be visible to read or write operations.)

CacheBuilder产生的缓存是可序列化的,序列化时保存了原有缓存的所有配置属性,缓存值的序列化只包括配置,不包括缓存的内容。

 

Method Summary

方法名 描述
static CacheBuilder<Object,ObjectnewBuilder() 创建一个默认配置的CacheBuilder
<K1 extends K,V1 extends V
CacheBuilder<K1,V1> removalListener(RemovalListener<? super K1,? super V1> listener)
指定一个监听器,当有键值对从缓存中清除时会进行通知
CacheBuilder<K,VmaximumSize(long size) 指定缓存中能缓存的最大键值对个数
CacheBuilder<K,VinitialCapacity(int initialCapacity) 设置哈希表的最小总大小
static CacheBuilder<Object,Objectfrom(String spec) 根据spec中指定的设置新建一个CacheBuilder
CacheBuilder<K,VexpireAfterWrite(long duration, TimeUnit unit) 指定在键值对的创建/替换值之后的一个固定时间后从缓存中自动删除该键值对

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!