一:適用場景
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(); }