Guava Cache 建立
基本上能够经过两种方式来建立cache:
cacheLoader
callable callback
经过这两种方法建立的cache,和一般用map来缓存的作法比,不一样在于,这两种方法都实现了一种逻辑——从缓存中取key X的值,若是该值已经缓存过了,则返回缓存中的值,若是没有缓存过,能够经过某个方法来获取这个值。
但不一样的在于cacheloader的定义比较宽泛,是针对整个cache定义的,能够认为是统一的根据key值load value的方法。
而callable的方式较为灵活,容许你在get的时候指定。
下面是两种方法的例子:
首先是基于cacheloader的方法 java
@Test public void testCacheBuilder() throws ExecutionException { LoadingCache<String, String> graphs = CacheBuilder.newBuilder() .maximumSize(1000) .build(new CacheLoader<String, String>() { public String load(String key) { // 这里是key根据实际去取值的方法 return "value"; } }); String resultVal = graphs.get("testKey"); System.out.println(resultVal); }
其次是基于实现callable的方法: 缓存
@Test public void testCallable() throws ExecutionException { // 没有使用CacheLoader Cache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(1000) .build(); String resultVal = cache.get("testKey", new Callable<String>() { public String call() { // 这里先根据key实际去取值的方法 return "value"; } }); System.out.println(resultVal); }
Guava Cache 数据的移除
被动移除数据的方式,guava默认提供了三种方式:
基于大小的移除
看字面意思就知道就是按照缓存的大小来移除,若是即将到达指定的大小,那就会把不经常使用的键值对从cache中移除。
定义的方式通常为 CacheBuilder.maximumSize(long),官方还介绍了一种能够算权重的方法,我的认为实际使用中不太用到,暂不讨论。
就这个经常使用的来看有几个注意点,
其一,这个size指的是cache中的条目数,不是内存大小或是其余;
其二,并非彻底到了指定的size系统才开始移除不经常使用的数据的,而是接近这个size的时候系统就会开始作移除的动做;
其三,若是一个键值对已经从缓存中被移除了,你再次请求访问的时候,若是cachebuild是使用cacheloader方式的,那依然仍是会从cacheloader中再取一次值,若是这样尚未,就会抛出异常
基于时间的移除
guava提供了两个基于时间移除的方法
expireAfterAccess(long, TimeUnit) 这个方法是根据某个键值对最后一次访问以后多少时间后移除
expireAfterWrite(long, TimeUnit) 这个方法是根据某个键值对被建立或值被替换后多少时间移除
基于引用的移除
这种移除方式主要是基于java的垃圾回收机制,根据键或者值的引用关系决定移除,我的对垃圾回收这块不是很是了解,窃觉得不太可靠。。也不经常使用。。因此没有研究,欢迎补充。
主动移除数据方式
主动移除有三种方法:
单独移除用 Cache.invalidate(key)
批量移除用 Cache.invalidateAll(keys)
移除全部用 Cache.invalidateAll()
若是须要在移除数据的时候有所动做还能够定义Removal Listener,可是有点须要注意的是默认Removal Listener中的行为是和移除动做同步执行的,若是须要改为异步形式,能够考虑使用RemovalListeners.asynchronous(RemovalListener, Executor)
Guava Cache 的清空,刷新及统计功能
主要介绍guava cache的清空,刷新和统计的功能。
缓存数据的清空
guava没有提供自动触发清空缓存数据的功能,而是提供了一种手工调用的方式,使用者须要经过Cache.cleanUp()的方式来清空缓存。
因此通常能够有两种选择,一种是经过某个请求来触发清空动做,这种至关于按需清空,另外一种则是经过定时任务,亦成为调度程序来清空,这种至关于与按时清空
缓存数据的刷新
guava没有提供相似refreshall的方法刷新缓存中的全部值,而只是提供了 LoadingCache.refresh(K)方法,用于刷新某个键值对,这里有趣的是刷新动做是异步的,也就是在值被完全刷新以前,若是有人取这个key的值,返回的仍是没有刷新的值。 异步
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() .maximumSize(1000) .refreshAfterWrite(1, TimeUnit.MINUTES) .build( new CacheLoader<Key, Graph>() { public Graph load(Key key) { // no checked exception return getGraphFromDatabase(key); } public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) { if (neverNeedsRefresh(key)) { return Futures.immediateFuture(prevGraph); } else { // asynchronous! return ListenableFutureTask.create(new Callable<Graph>() { public Graph call() { return getGraphFromDatabase(key); } }); } } });缓存数据统计