【拉勾GuavaCache-2】高级应用

文章内容输出来源:拉勾教育Java高薪训练营

希望记录的每一个点,都能真正掌握,而不是流水账

上一篇讲解了基本使用,这一篇来看一些高级知识点

 

一:并发设置

使用concurrencyLevel属性设置并发线程数,该值就是segment数组长度,如ConcurrentHashMap一般,数组多长就支持多少个并发。

LoadingCache<String,Object> cache = CacheBuilder.newBuilder()
// 最大3个 同时支持CPU核数线程写缓存
.maximumSize(3).concurrencyLevel(Runtime.getRuntime().availableProcessors()).build();
V get(K key, CacheLoader<? super K, V> loader) throws ExecutionException {
int hash = this.hash(Preconditions.checkNotNull(key));
//通过hash值确定该key位于哪一个segment上,并获取该segment
return this.segmentFor(hash).get(key, hash, loader);
}
二:更新锁定
 
如下,refreshAfterWrite指定,在3s内没有写操作更新,则回源查询新值,没有则返回旧值。  关键在于,回源只会有一个请求,其他请求会阻塞等待,避免缓存穿透造成雪崩。
 

 LoadingCache<String,Object> cache = CacheBuilder.newBuilder()

// 最大3个 同时支持CPU核数线程写缓存
.maximumSize(3).concurrencyLevel(Runtime.getRuntime().availableProcessors()).
//3秒内阻塞会返回旧数据
refreshAfterWrite(3,TimeUnit.SECONDS).build();
三:疑难问题:
 
1、会发生oom吗 (内存溢出)?
会发生。 所以我们要注意设置缓存过期,数量的设置也要考虑实际内存大小。 另外,可以使用弱引用方式缓存对象,这样可以及时被回收。
Cache<String, String> cache = CacheBuilder.newBuilder() .expireAfterWrite(1, TimeUnit.SECONDS).weakValues().build();
2、缓存到期就会立即被清除吗?
不是的。 是在每次操作缓存时候,如读取或更新时判断是否过期,主动删除。
3、如何找出最久未使用的数据?
使用访问队列,该队列会把新访问的数据放到队列末尾,在队首的就是最久的。
【拉勾GuavaCache-2】高级应用
 
那么,对于最久未更新的,就可以使用写队列了。