guava cache很適合做進程內的緩存,本文先學習下它的緩存統計功能,需要使用recordStats()打開緩存統計功能。
// 創建1塊緩存,key和value都是integer類型,最大緩存個數是5,開啓緩存統計功能
// 使用LoadingCache,如果數據不存在就使用CacheLoader加載數據
LoadingCache cache = CacheBuilder.newBuilder().recordStats().maximumSize(5).
build(new CacheLoader<Integer, Integer>() {
@Override
public Integer load(Integer id) throws Exception {
System.out.println("mock query db....");
if (id % 2 == 0) {
Thread.sleep(100);
throw new RuntimeException();
} else {
Thread.sleep(200);
return id * 10;
}
}
});
CacheStats的javadoc已經很清楚地描述了緩存統計的一些規則:
// 預先添加一條緩存數據
cache.put(1, 100);
System.out.println("...." + cache.stats());
// 緩存命中,hitCount加1
System.out.println("get data====" + cache.get(1));
System.out.println("...." + cache.stats());
// 沒有命中緩存, missCount和loadSuccessCount加1,並增加totalLoadTime(納秒爲單位)
System.out.println("get data====" + cache.get(3));
System.out.println("...." + cache.stats());
// 沒有命中緩存, missCount和loadExceptionCount加1,並增加totalLoadTime(納秒爲單位)
try {
System.out.println("get data====" + cache.get(4));
} catch (Exception e) {
System.out.println("...." + cache.stats());
}
// 手動清除緩存數據,或者是直接操作緩存底層數據,不會影響統計信息
System.out.println("get data====" + cache.asMap().get(1));// 通過緩存底層數據結構,讀取數據
cache.invalidateAll();// 清空緩存
System.out.println("...." + cache.stats());
// 添加6條緩存數據,由於最大數目是5,所以evictionCount=1
System.out.println("size===" + cache.size());
cache.put(1, 100);
cache.put(2, 100);
cache.put(3, 100);
cache.put(4, 100);
cache.put(5, 100);
cache.put(6, 100);
System.out.println("...." + cache.stats());
有一點需要注意下:可以通過修改底層map給緩存添加數據,也可以獲取數據。通過map獲取數據,不會影響緩存統計;通過map添加數據,會影響evictionCount。
// 創建1塊緩存,key和value都是integer類型,最大緩存個數是5,開啓緩存統計功能
// 使用LoadingCache,如果數據不存在就使用CacheLoader加載數據
LoadingCache cache = CacheBuilder.newBuilder().recordStats().maximumSize(5).
build(new CacheLoader<Integer, Integer>() {
@Override
public Integer load(Integer id) throws Exception {
System.out.println("mock query db....");
if (id % 2 == 0) {
Thread.sleep(100);
throw new RuntimeException();
} else {
Thread.sleep(200);
return id * 10;
}
}
});
// 修改底層的map也會導致cache發生變化
ConcurrentMap underlingMap = cache.asMap();
underlingMap.put(1, 1);
underlingMap.put(2, 2);
underlingMap.put(3, 3);
underlingMap.put(4, 4);
underlingMap.put(5, 5);
underlingMap.put(6, 6);
System.out.println("underlingMap...." + underlingMap);
System.out.println("cache...." + cache.size());
// evictionCount=1
System.out.println("stats...." + cache.stats());