GuavaCache是Guava中的缓存框架,与ConcurrentMap很相似,不一样的是,ConcurrentMap中的元素会一直保留直到显式的移除,而GuavaCache为了限制内存占用,通常会设定为自动回收元素。
与传统的缓存方案相比,如redis,GuavaCache是将数据放在内存当中,访问起来更加高效,并且GuavaCache将很多常见的业务场景进行高度封装,使用起来非常灵活,对内存中的数据管理也有更多的方案。
Guava官网介绍,下面的这几种情况可以考虑使用Guava Cache:
- 愿意消耗一些内存空间来提升速度。
- 预料到某些键会被多次查询。
- 缓存中存放的数据总量不会超出内存容量。
可以通过CacheBuilder类构建一个缓存对象,CacheBuilder采用builder设计模式,它的每个方法都返回CacheBuilder本身,直到build()方法被调用。构建一个对象的代码如下:
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().build();
cache.put("hello", "hello world");
System.out.println(cache.getIfPresent("hello"));
}
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(3).build();
cache.put("hello", "hello world");
System.out.println(cache.getIfPresent("hello"));
cache.put("hello1", "hello world1");
cache.put("hello2", "hello world2");
cache.put("hello3", "hello world3");
System.out.println(cache.getIfPresent("hello"));
System.out.println(cache.getIfPresent("hello1"));
System.out.println(cache.getIfPresent("hello2"));
System.out.println(cache.getIfPresent("hello3"));
}
hello world
null
hello world1
hello world2
hello world3
expireAfterWrite是设置put到Cache的对象3秒过期,不论中间有没有被访问。
public void buildCache() throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(3, TimeUnit.SECONDS).maximumSize(3).build();
cache.put("hello", "hello world");
for(int i=0;;i++){
System.out.println("第"+i+"次获取key的值:"+ cache.getIfPresent("hello"));
Thread.sleep(1000L);
}
}
第0次获取key的值:hello world
第1次获取key的值:hello world
第2次获取key的值:hello world
第3次获取key的值:null
第4次获取key的值:null
第5次获取key的值:null
第6次获取key的值:null
expireAfterAccess是设置Cache中对象超过3秒没有被访问就会过期。
public void buildCache() throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.SECONDS).maximumSize(3).build();
cache.put("hello", "hello world");
for (int i = 0; ; i++) {
System.out.println("第" + i + "秒获取key的值:" + cache.getIfPresent("hello"));
Thread.sleep(i * 1000L);
}
}
第0秒获取key的值:hello world
第1秒获取key的值:hello world
第2秒获取key的值:hello world
第3秒获取key的值:hello world
第4秒获取key的值:null
第5秒获取key的值:null
第6秒获取key的值:null
可以调用Cache的invalidateAll批量移除记录或者调用invalidate移除Cache中的一个记录,invalidateAll的参数是Iterable类型的,参数包含要删除的key值,当没有传入任何参数时,invalidateAll将移除Cache中所有的记录。
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().build();
cache.put("hello1","world1");
cache.put("hello2","world2");
cache.put("hello3","world3");
cache.put("hello4","world4");
//cache.invalidate("hello2");
List<String> list = new ArrayList<>();
list.add("hello2");
list.add("hello3");
cache.invalidateAll(list);
System.out.println(cache.getIfPresent("hello1"));
System.out.println(cache.getIfPresent("hello2"));
System.out.println(cache.getIfPresent("hello3"));
System.out.println(cache.getIfPresent("hello4"));
}
world1
null
null
world4
public void buildCache() {
RemovalListener<String, String> listener = removalNotification -> System.out.println(removalNotification.getKey()
+ ":" + removalNotification.getValue() + " is removed");
Cache<String, String> cache = CacheBuilder.newBuilder().removalListener(listener).maximumSize(3).build();
cache.put("hello1", "world1");
cache.put("hello2", "world2");
cache.put("hello3", "world3");
cache.put("hello4", "world4");
cache.put("hello5", "world5");
}
hello1:world1 is removed
hello2:world2 is removed
以上列举了GuavaCache常用几种方法,源码请移步下方地址获取:
https://github.com/google/guava