一、GuavaCache的介绍
GuavaCache是一个本地缓存,有以下优点:
很好的封装了get、put操作,能够集成数据源。一般我们在业务中操作缓存都会操作缓存和数据源两部分。例如:put数据时,先插入DB 再删除原来的缓存,get数据时,先查缓存,命中则返回,没有命中时需要查询DB,再把查询结果放入缓存中。Guava封装了这么多步骤,只需要调用一次get/put方法即可。它是线程安全的缓存,与ConcurrentMap相似,但前者增加了更多的元素失效策略,后者只能显示的移除元素。GuavaCache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。定时回收有两种:按照写入时间,最早写入的最先回收;按照访问时间,最早访问的最早回收。它可以监控加载/命中情况。
二、GuavaCache的使用
【测试代码01】
package mytest
;
import com
.google
.common
.cache
.CacheBuilder
;
import com
.google
.common
.cache
.CacheLoader
;
import com
.google
.common
.cache
.LoadingCache
;
import java
.util
.concurrent
.ExecutionException
;
import java
.util
.concurrent
.TimeUnit
;
public class GuavaTest {
public static void main(String
[] args
) {
LoadingCache
<String, Integer> cache
= CacheBuilder
.newBuilder()
.maximumSize(10)
.expireAfterWrite(10, TimeUnit
.SECONDS
)
.recordStats()
.build(new CacheLoader<String, Integer>() {
@Override
public Integer
load(String key
) throws Exception
{
return -1;
}
});
System
.out
.println(cache
.getIfPresent("key1"));
cache
.put("key1", 1);
System
.out
.println(cache
.getIfPresent("key1"));
try {
System
.out
.println(cache
.get("key2"));
cache
.put("key2", 2);
System
.out
.println(cache
.get("key2"));
System
.out
.println("size:" + cache
.size());
for (int i
= 3; i
< 13; i
++) {
cache
.put("key"+i
, i
);
}
System
.out
.println("size:" + cache
.size());
System
.out
.println(cache
.getIfPresent("key2"));
Thread
.sleep(5000);
cache
.put("key1", 1);
cache
.put("key2", 2);
System
.out
.println(cache
.getIfPresent("key5"));
Thread
.sleep(5000);
System
.out
.println("size :" + cache
.size());
System
.out
.println(cache
.getIfPresent("key1"));
System
.out
.println("size :" + cache
.size());
System
.out
.println(cache
.getIfPresent("key5"));
System
.out
.println("size :" + cache
.size());
System
.out
.println("status, hitCount:" + cache
.stats().hitCount()
+ ", missCount:" + cache
.stats().missCount());
Thread
.sleep(10000);
System
.out
.println("size :" + cache
.size());
System
.out
.println(cache
.getIfPresent("key1"));
} catch (ExecutionException e
) {
e
.printStackTrace();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
}
运行结果:
null 1 -1 2 size:2 size:10 null 5 size :10 1 size :10 null size :2 status, hitCount:4, missCount:4 size :2 null
【测试代码02】
package mytest
;
import java
.util
.concurrent
.Callable
;
import java
.util
.concurrent
.TimeUnit
;
import com
.google
.common
.cache
.Cache
;
import com
.google
.common
.cache
.CacheBuilder
;
import com
.google
.common
.cache
.RemovalListener
;
import com
.google
.common
.cache
.RemovalNotification
;
public class GuavaTest02 {
public static Cache
<String, String> caches
= CacheBuilder
.newBuilder().
maximumSize(128)
.expireAfterAccess(3, TimeUnit
.SECONDS
)
.removalListener(new RemovalListener<String, String>() {
@Override
public void onRemoval(RemovalNotification
<String, String> notification
) {
System
.out
.println(notification
.getKey());
}
}).build();
public static String
get(final String key
) throws Exception
{
String rr
= caches
.get(key
, new Callable<String>() {
@Override
public String
call() throws Exception
{
if ("1".equalsIgnoreCase(key
)) {
return "test";
}
throw new Exception("This is a test!");
}
});
return rr
;
}
public static void main(String
[] args
) throws Exception
{
System
.out
.println(GuavaTest02
.get("1"));
System
.out
.println("before expire: " + GuavaTest02
.caches
.asMap().keySet());
Thread
.sleep(5000);
System
.out
.println("after expire: " + GuavaTest02
.caches
.asMap().keySet());
}
}
运行结果:
test before expire: [1] after expire: []