一:适用场景
1.“尺寸较小”、“高频的读取操作”、“变更操作较少”,这样的场景下比较适合Guava这种“嵌入式”缓存;
2.当然对于一些“数据较大”、“需要一定的持久化”保障的,需要考虑redis、memcached等分布式缓存
二:使用
1.创建方式:使用CacheLoader:这样可以直接使用cache.get(key)即可
public static com.google.common.cache.CacheLoader<String, String> createCacheLoader() { return new com.google.common.cache.CacheLoader<String, String>() { @Override public String load(String key) throws Exception { log.info("加载创建key:" + key); return ""; } }; } LoadingCache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterAccess(30L, TimeUnit.MILLISECONDS) .build(createCacheLoader());
2.创建方式:普通的创建,但是get时,需要传入Callable参数,或者getIfPresent()
private static final Cache<String, String> settingsCache = CacheBuilder.newBuilder().concurrencyLevel(10) .maximumSize(10).initialCapacity(8).build();
/**获取方式1,不存在会返回null*/ String value = settingsCache.getIfPresent(key);
/**获取方式2,不存在会使用Callable去加载*/ String value2 = settingsCache.get(key, () ->{ log.error("from settingsdao xxxxxxxxxxxxxx"); return new SettingsDaoCommand(settingsDao, key, defaultValue).execute(); });
3.创建参数
1.initialCapacity 初始化大小,因为Guava是继承的Map,所以也需要设置一个合适的初始化大小;
2.maximumSize,Cache的最大容量数,当缓存数量达到或接近该最大值时,Cache将清除掉那些最近最少使用的缓存;
3.maximumWeight,Cache的最大权重容量数,当当前key的的weight大于该值时,会被清除;
4.concurrencyLevel,同一时间最大的并发数;
5.expireAfterWrite(10, TimeUnit.SECONDS),设置cache中的数据在写入之后的存活时间为10S;
6.refreshAfterWrite(2, TimeUnit.SECONDS),2秒后会刷新值,缓存项只有在被检索时才会真正刷新;
efreshAfterWrite和expireAfterWrite两个方法设置以后, 重新get和loading操作都是同步串行的,所以这个时候的get
是获取不到数据的。
三:常用的操作
/** * 该接口的实现被认为是线程安全的,即可在多线程中调用 * 通过被定义单例使用 */ public interface Cache<K, V> { /** * 通过key获取缓存中的value,若不存在直接返回null */ V getIfPresent(Object key); /** * 通过key获取缓存中的value,若不存在就通过valueLoader来加载该value * 整个过程为 "if cached, return; otherwise create, cache and return" * 注意valueLoader要么返回非null值,要么抛出异常,绝对不能返回null */ V get(K key, Callable<? extends V> valueLoader) throws ExecutionException; /** * 添加缓存,若key存在,就覆盖旧值 */ void put(K key, V value); /** * 删除该key关联的缓存 */ void invalidate(Object key); /** * 删除所有缓存 */ void invalidateAll(); /** * 执行一些维护操作,包括清理缓存 */ void cleanUp(); }