一、引子
缓存有很多种解决方案,常见的是:
1.存储在内存中 : 内存缓存顾名思义直接存储在JVM内存中,JVM宕机那么内存丢失,读写速度快,但受内存大小的限制,且有丢失数据风险。
2.存储在磁盘中: 即从内存落地并序列化写入磁盘的缓存,持久化在磁盘,读写需要IO效率低,但是安全。
3.内存+磁盘组合方式:这种组合模式有很多成熟缓存组件,也是高效且安全的策略,比如redis。
本文分析常用的内存缓存:google cache。源码包:com.google.guava:guava:22.0 jar包下的pcom.google.common.cache包,适用于高并发读写场景,可自定义缓存失效策略。
二、使用方法
2.1 CacheBuilder有3种失效重载模式
1.expireAfterWrite
当 创建 或 写之后的 固定 有效期到达时,数据会被自动从缓存中移除,源码注释如下:
1 /**指明每个数据实体:当 创建 或 最新一次更新 之后的 固定值的 有效期到达时,数据会被自动从缓存中移除 2 * Specifies that each entry should be automatically removed from the cache once a fixed duration 3 * has elapsed after the entry's creation, or the most recent replacement of its value. 4 *当间隔被设置为0时,maximumSize设置为0,忽略其它容量和权重的设置。这使得测试时 临时性地 禁用缓存且不用改代码。 5 * <p>When { @code duration} is zero, this method hands off to { @link #maximumSize(long) 6 * maximumSize}{ @code (0)}, ignoring any otherwise-specified maximum size or weight. This can be 7 * useful in testing, or to disable caching temporarily without a code change. 8 *过期的数据实体可能会被Cache.size统计到,但不能进行读写,数据过期后会被清除。 9 * <p>Expired entries may be counted in { @link Cache#size}, but will never be visible to read or 10 * write operations. Expired entries are cleaned up as part of the routine maintenance described 11 * in the class javadoc. 12 * 13 * @param duration the length of time after an entry is created that it should be automatically 14 * removed 15 * @param unit the unit that { @code duration} is expressed in 16 * @return this { @code CacheBuilder} instance (for chaining) 17 * @throws IllegalArgumentException if { @code duration} is negative 18 * @throws IllegalStateException if the time to live or time to idle was already set 19 */ 20 public CacheBuilder<K, V> expireAfterWrite(long duration, TimeUnit unit) { 21 checkState( 22 expireAfterWriteNanos == UNSET_INT, 23 "expireAfterWrite was already set to %s ns", 24 expireAfterWriteNanos); 25 checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); 26 this.expireAfterWriteNanos = unit.toNanos(duration); 27 return this; 28 }
2.expireAfterAccess
指明每个数据实体:当 创建 或 写 或 读 之后的 固定值的有效期到达时,数据会被自动从缓存中移除。读写操作都会重置访问时间,但asMap方法不会。源码注释如下:
1 /**指明每个数据实体:当 创建 或 更新 或 访问 之后的 固定值的有效期到达时,数据会被自动从缓存中移除。读写操作都会重置访问时间,但asMap方法不会。 2 * Specifies that each entry should be automatically removed from the cache once a fixed duration 3 * has elapsed after the entry's creation, the most recent replacement of its value, or its last 4 * access. Access time is reset by all cache read and write operations (including 5 * { @code Cache.asMap().get(Object)} and { @code Cache.asMap().put(K, V)}), but not by operations 6 * on the collection-views of { @link Cache#asMap}. 7 * 后面的同expireAfterWrite 8 * <p>When { @code duration} is zero, this method hands off to { @link #maximumSize(long) 9 * maximumSize}{ @code (0)}, ignoring any otherwise-specified maximum size or weight. This can be 10 * useful in testing, or to disable caching temporarily without a code change. 11 * 12 * <p>Expired entries may be counted in { @link</