Google Guava学习之Cache

what、why、how三部曲

1.GuavaCache是什么?

GuavaCache是Guava中的缓存框架,与ConcurrentMap很相似,不一样的是,ConcurrentMap中的元素会一直保留直到显式的移除,而GuavaCache为了限制内存占用,通常会设定为自动回收元素。

2.什么时候用GuavaCache?

与传统的缓存方案相比,如redis,GuavaCache是将数据放在内存当中,访问起来更加高效,并且GuavaCache将很多常见的业务场景进行高度封装,使用起来非常灵活,对内存中的数据管理也有更多的方案。
Guava官网介绍,下面的这几种情况可以考虑使用Guava Cache:
- 愿意消耗一些内存空间来提升速度。
- 预料到某些键会被多次查询。
- 缓存中存放的数据总量不会超出内存容量。

3.如何使用GuavaCache?

1. 构建缓存对象

可以通过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"));
}
2. 设置最大存储量
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
3. 设置过期时间

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
4. 显示清除

可以调用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
5. 移除监听器
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章