Guava Cache 工具類 [ GuavaCacheUtil ]
阿新 • • 發佈:2019-01-04
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
package com.app.core.util; import com.google.common.cache.*; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.ObjectUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; @Log4j2 public class GuavaCacheUtil { /** * 快取項最大數量 */ private static final long GUAVA_CACHE_SIZE = 100000; /** * 快取時間:分鐘 */ private static final long GUAVA_CACHE_TIME = 10; /** * 快取操作物件 */ private static LoadingCache<String, Object> GLOBAL_CACHE = null; static { try { GLOBAL_CACHE = loadCache(new CacheLoader<String, Object>() { public Object load(String key) throws Exception { // 該方法主要是處理快取鍵不存在快取值時的處理邏輯 if (log.isDebugEnabled()) log.debug("Guava Cache快取值不存在,初始化空值,鍵名:{}", key); return ObjectUtils.NULL; } }); } catch (Exception e) { log.error("初始化Guava Cache出錯", e); } } /** * 全域性快取設定 * <ul> * <li>快取項最大數量:100000</li> * <li>快取有效時間(分鐘):10</li> * </ul> * * @param cacheLoader * @return * @throws Exception */ private static <K, V> LoadingCache<K, V> loadCache(CacheLoader<K, V> cacheLoader) throws Exception { /* * maximumSize 快取池大小,在快取項接近該大小時, Guava開始回收舊的快取項 expireAfterAccess 表示最後一次使用該快取項多長時間後失效 removalListener 移除快取項時執行的邏輯方法 recordStats 開啟Guava Cache的統計功能 */ LoadingCache<K, V> cache = CacheBuilder.newBuilder().maximumSize(GUAVA_CACHE_SIZE).expireAfterAccess(GUAVA_CACHE_TIME, TimeUnit.MINUTES) .removalListener(new RemovalListener<K, V>() { public void onRemoval(RemovalNotification<K, V> rn) { if (log.isDebugEnabled()) log.debug("Guava Cache快取回收成功,鍵:{}, 值:{}", rn.getKey(), rn.getValue()); } }).recordStats().build(cacheLoader); return cache; } /** * 設定快取值 * * @param key * @param value */ public static void put(String key, Object value) { try { GLOBAL_CACHE.put(key, value); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("設定快取值出錯", e); } } /** * 批量設定快取值 * * @param map */ public static void putAll(Map<? extends String, ? extends Object> map) { try { GLOBAL_CACHE.putAll(map); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("批量設定快取值出錯", e); } } /** * 獲取快取值 * <p>注:如果鍵不存在值,將呼叫CacheLoader的load方法載入新值到該鍵中</p> * * @param key * @return */ public static Object get(String key) { Object obj = null; try { obj = GLOBAL_CACHE.get(key); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("獲取快取值出錯", e); } return obj; } /** * 獲取快取值 * <p>注:如果鍵不存在值,將直接返回 NULL</p> * * @param key * @return */ public static Object getIfPresent(String key) { Object obj = null; try { obj = GLOBAL_CACHE.getIfPresent(key); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("獲取快取值出錯", e); } return obj; } /** * 移除快取 * * @param key */ public static void remove(String key) { try { GLOBAL_CACHE.invalidate(key); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("移除快取出錯", e); } } /** * 批量移除快取 * * @param keys */ public static void removeAll(Iterable<String> keys) { try { GLOBAL_CACHE.invalidateAll(keys); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("批量移除快取出錯", e); } } /** * 清空所有快取 */ public static void removeAll() { try { GLOBAL_CACHE.invalidateAll(); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("清空所有快取出錯", e); } } /** * 獲取快取項數量 * * @return */ public static long size() { long size = 0; try { size = GLOBAL_CACHE.size(); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("獲取快取項數量出錯", e); } return size; } /** * 獲取所有快取項的鍵 * * @return */ public static List<String> keys() { List<String> list = new ArrayList<String>(); try { ConcurrentMap<String, Object> map = GLOBAL_CACHE.asMap(); for (Map.Entry<String, Object> item : map.entrySet()) list.add(item.getKey()); if (log.isDebugEnabled()) log.debug("快取命中率:{},新值平均載入時間:{}", getHitRate(), getAverageLoadPenalty()); } catch (Exception e) { log.error("獲取所有快取項的鍵出錯", e); } return list; } /** * 快取命中率 * * @return */ public static double getHitRate() { return GLOBAL_CACHE.stats().hitRate(); } /** * 載入新值的平均時間,單位為納秒 * * @return */ public static double getAverageLoadPenalty() { return GLOBAL_CACHE.stats().averageLoadPenalty(); } /** * 快取項被回收的總數,不包括顯式清除 * * @return */ public static long getEvictionCount() { return GLOBAL_CACHE.stats().evictionCount(); } }