Guava CacheBuilder使用说明
2016-08-03 00:00
323 查看
摘要: 结合代码介绍Guava CacheBuilder类以及用CacheBuilder构建的缓存实例具有的特性。
CacheBuilder是Guava用于创建LoadingCache、Cache实例的构建类。可以使用下面的方法来创建一个Cache实例。
将数据写入缓存时是原子操作。
当缓存的数据达到最大规模时,会使用“最近最少使用(LRU)”算法来清除缓存数据。
每一条数据还可以基于时间回收,未使用时间超过一定时间后,数据会被回收。
当缓存被清除时,会发送通知告知。
提供访问统计功能。
通常情况下,缓存通过Object对象的equals方法来比对键值。但是当缓存指定成 weakKeys 类型后,键值的对比将会使用 “==”来比对。同样的,当指定为 weakValues 或 softValues 类型后,会使用"=="来比对存储值。
当设置了maximumSize、maximumWeight、expireAfterWrite、expireAfterAccess、weakKeys、weakValues、softValues等参数后,缓存的数据会根据规则自动被清除。
如果设置maximumSize、maximumWeight,在每次修改缓存数据时,都有可能有数据被清除。
如果设置了expireAfterWrite或expireAfterAccess参数,当每个缓存被修改、访问缓存数据或调用Cache::cleanUp方法时某些数据可能会被清除。此时被清除的数据,调用Cache::size时还会被计数,但是已无法被读写。
如果设置了weakKeys、weakValues、softValues,可能会出现某些存储在缓存中的数据被GC回收的情况。这些已经被回收的缓存数据会在缓存被修改、访问缓存、或调用Cache::cleanUp方法时被清除。这些被清除的数据在调用Cache::size时还会被计数,但是已无法读写。
某些缓存的配置会让缓存启动定期维护任务,任务会读写操作后被执行。调用Cache::cleanUp方法时,也会启用缓存维护任务。请勿在用于高吞吐量的缓存中调用Cache::cleanUp方法。当设置了removalListener、expireAfterWrite、expireAfterAccess、weakKeys、weakValues、softValues后,会导致维护任务运行。
由CacheBuilder创建的缓存可以被序列化和反序列化。序列化时会写入所有的配置信息,但是不会写入任何缓存数据信息。
CacheBuilder是Guava用于创建LoadingCache、Cache实例的构建类。可以使用下面的方法来创建一个Cache实例。
LoadingCache<String, JsonObject> cacheDemo = CacheBuilder.newBuilder().concurrencyLevel(5).expireAfterAccess(30, TimeUnit.MINUTES).initialCapacity(100).maximumSize(5000) .recordStats().removalListener(entry -> { LOG.info("remove cache! Entry key = " + entry.getKey()); }).build(new CacheLoader<String, JsonObject>() { @Override public JsonObject load(String key) throws Exception { return readEntryFromDb(key); } });
Guava CacheBuilder构建的缓存特性
通过CacheBuilder构建的Cache实例具有以下特性:将数据写入缓存时是原子操作。
当缓存的数据达到最大规模时,会使用“最近最少使用(LRU)”算法来清除缓存数据。
每一条数据还可以基于时间回收,未使用时间超过一定时间后,数据会被回收。
当缓存被清除时,会发送通知告知。
提供访问统计功能。
使用Guava CacheBuilder需要了解的细节
通过CacheBuilder创建缓存实例的数据结构是一个hash table,其性能和特征都类似于ConcurrentHashMap。它实现了LoadingCache的所有方法和Cache接口。调用Cache::asMap接口时,会返回一个 “弱关联属性的iterators”,这意味着当获取了这个ConcurrentMap之后,当前线程操作缓存的结果都会立刻在ConcurrentMap上生效,但是不能确保其他线程修改的缓存数据会映射到已获取ConcurrentMap中。通常情况下,缓存通过Object对象的equals方法来比对键值。但是当缓存指定成 weakKeys 类型后,键值的对比将会使用 “==”来比对。同样的,当指定为 weakValues 或 softValues 类型后,会使用"=="来比对存储值。
当设置了maximumSize、maximumWeight、expireAfterWrite、expireAfterAccess、weakKeys、weakValues、softValues等参数后,缓存的数据会根据规则自动被清除。
如果设置maximumSize、maximumWeight,在每次修改缓存数据时,都有可能有数据被清除。
如果设置了expireAfterWrite或expireAfterAccess参数,当每个缓存被修改、访问缓存数据或调用Cache::cleanUp方法时某些数据可能会被清除。此时被清除的数据,调用Cache::size时还会被计数,但是已无法被读写。
如果设置了weakKeys、weakValues、softValues,可能会出现某些存储在缓存中的数据被GC回收的情况。这些已经被回收的缓存数据会在缓存被修改、访问缓存、或调用Cache::cleanUp方法时被清除。这些被清除的数据在调用Cache::size时还会被计数,但是已无法读写。
某些缓存的配置会让缓存启动定期维护任务,任务会读写操作后被执行。调用Cache::cleanUp方法时,也会启用缓存维护任务。请勿在用于高吞吐量的缓存中调用Cache::cleanUp方法。当设置了removalListener、expireAfterWrite、expireAfterAccess、weakKeys、weakValues、softValues后,会导致维护任务运行。
由CacheBuilder创建的缓存可以被序列化和反序列化。序列化时会写入所有的配置信息,但是不会写入任何缓存数据信息。
CacheBuilder方法说明
initialCapacity(int initialCapacity)
指定用于缓存的hash table最低总规模。——例如设置了initialCapacity为60,还设置了concurrencyLevel(参阅下文说明)为8。将会把存储的空间分为8块,每块都有一个hash table结构,每个hash table的初始规模为8。如果缓存空间有限,需要预估足够大的初始化空间来缓,避免在数据增长时昂贵的扩展操作(扩展空间会导致深度COPY)。concurrencyLevel(int concurrencyLevel)
允许同时并发更新操作数。是指对一个缓存中的数据进行更新操作时的并发量。设置这个参数后,允许并发的最大量不一定会严格遵守这个参数。因为数据被分别存储到不同的区块中,而这些数据并不是均匀分布的。在代码实现中,缓存在将会根据这个参数创建对应的ConcurrentMap个数,每一个ConcurrentMap称为一个区块。数据会分别存储到每个ConcurrentMap上,还会有另外一个数据结构来维护所有缓存数据所在的位置。因此,如果将这个参数设置过大,会导致更多时间和空间上的开销(分配了更多的区块,需要额外维护这些区块信息);如果设置过小,会导致在更新操作时,有大量的线程阻塞(更新同一个ConcurrentMap需要等待锁)。maximumSize(long size)
允许最大的缓存条目数。需要注意的是,在数据条目数达到maximumSize之前,就可能发生数据回收事件。在缓存的数据快要达到规模上限时,缓存就会回收可能不再会使用的数据。maximumWeight(long weight)
数据清除权重。在缓存的使用中,这个权重的概率很难理解,简单的说就是:每个参数在进入缓存之前都会使用用户自定义的Weigher对象来运算每条数据的权重值。在进行数据释放时,会参考数据的权重值和设定的“maximumWeight”来确定哪条数据需要被回收。声明代码如下: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); } });
weakKeys()
将缓存中的key设置成weakKey模式。默认情况下,会使用“强关系”来保存key值。当设置为weakKey时,会使用(==)来匹配key值。在使用weakKey的情况下,数据可能会被GC。数据被GC后,可能仍然会被size方法计数,但是对其执行read或write方法已经无效。weakValues()
将缓存中的数据设置为weakValues模式。启用weakValue设置时,某些数据会被GC。默认情况下,会使用“强关系”来保存key值。当设置为weakValue时,会使用(==)来匹配value值。数据被GC后,可能仍然会被size方法计数,但是对其执行read或write方法已经无效。softValues()
将缓存中的数据设置为softValues模式。使用这个模式时,所有的数据都使用SoftReference类对缓存中的数据进行包裹(就是在SoftReference实例中存储真实的数据)。使用SoftReference包裹的数据,会被全局垃圾回收管理器托管,按照LRU的原则来定期GC数据。数据被GC后,可能仍然会被size方法计数,但是对其执行read或write方法已经无效。相关文章推荐
- 使用spring3 cacheManager配置Guava Cache和Redis Cache
- DllCacheManager使用说明
- Spring cache简单使用guava cache
- guava cache使用例子
- guava cache使用例子
- guava Cache使用心得
- Guava------------Cache使用方法
- 1.Guava------------Cache使用方法
- 是什么让spring 5放弃了使用Guava Cache?
- Sandcastle和Sandcastle Help File Builder使用说明
- xsqlbuilder使用说明
- Guava缓存器源码分析——CacheBuilderSpec
- xhttpcache 使用详细说明
- 【Android】 import跟export使用说明 及 export报错:jarlist.cache: Resource is out of sync with the file syst解决
- AggregateCacheDependency、CacheDependency、SqlCacheDependency Asp.net 2.0和Sql Server的缓存管理和使用ObjectBuilder改造PetShop4 的缓存示例
- Eclipse使用技巧(五)SWT Designer 5.0 (Window Builder Pro) For eclipse 3.2 安装及注册说明
- Google Guava 工具集__2__Cache 缓存使用
- Guava之controller中使用缓存cache
- Google Guava -缓存cache简单使用
- Google Guava之--cache 使用