Guava用法

一、简介
Google Guava包含了Google的Java项目许多依赖的库,如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。本文只介绍其中的缓存部分。
Guava Cache是一种本地缓存实现,支持多种缓存过期策略。性能好,简单易用。缓存在很多场景下都是很有用的。如,通过key获取一个value的花费的时间很多,而且获取的次数不止一次的时候,就应该考虑使用缓存。Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。而Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也会自动加载缓存。

Guava Cache适用于以下应用场景:

  • 系统的访问速度首要考虑,而内存空间为次要考虑。
  • 某些key对于的value会被查询多次。
  • 缓存中存放的数据总量不会超出内存的全部大小。

二、相关方法

显式插入:该方法可以直接向缓存中插入值,如果缓存中有相同key则之前的会被覆盖。

cache.put(key, value);

显式清除:我们也可以对缓存进行手动清除。

cache.invalidate(key); //单个清除cache.invalidateAll(keys); //批量清除cache.invalidateAll(); //清除所有缓存项

基于时间的移除: 

expireAfterAccess( long, TimeUnit); 该键值对最后一次访问后超过指定时间再移除expireAfterWrite(long, TimeUnit) ;该键值对被创建或值被替换后超过指定时间再移除

基于大小的移除:指如果缓存的对象格式即将到达指定的大小,就会将不常用的键值对从cache中移除。

cacheBuilder.maximumSize( long)

size是指cache中缓存的对象个数。当缓存的个数开始接近size的时候系统就会进行移除的操作

缓存清除执行的时间

  • V getIfPresent(Object key) 获取缓存中key对应的value,如果缓存没命中,返回null。return value if cached, otherwise return null.
  • V get(K key) throws ExecutionException 获取key对应的value,若缓存中没有,则调用LocalCache的load方法,从数据源中加载,并缓存。 return value if cached, otherwise load, cache and return.
  • void put(K key, V value) if cached, return; otherwise create, cache , and return.
  • void invalidate(Object key); 删除缓存
  • void invalidateAll(); 清楚所有的缓存,相当远map的clear操作。
  • long size(); 获取缓存中元素的大概个数。为什么是大概呢?元素失效之时,并不会实时的更新size,所以这里的size可能会包含失效元素。
  • CacheStats stats(); 缓存的状态数据,包括(未)命中个数,加载成功/失败个数,总共加载时间,删除个数等。
  • ConcurrentMap<K, V> asMap(); 将缓存存储到一个线程安全的map中。

使用CacheBuilder构建的缓存不会"自动"执行清理和回收工作,也不会在某个缓存项过期后马上清理,也没有诸如此类的清理机制。它是在写操作时顺带做少量的维护工作(清理);如果写操作太少,读操作的时候也会进行少量维护工作。因为如果要自动地持续清理缓存,就必须有一个线程,这个线程会和用户操作竞争共享锁。在某些环境下线程创建可能受限制,这样CacheBuilder就不可用了。

三、Guava用法

Guava用法Guava的一个比较常见用法就是一个缓冲的用法,下面就是专门介绍这个缓存的具体用法。第一LoadingCache和CacheLoader的区别,前者是专门用来缓存的,后者是定义加载方式,而后者一般会有三种重载方法。CacheLoaderCacheLoaderbaseLoader=newCacheLoader(){@OverridepublicObjectload(Objectkey){loadCount.incrementAndGet();returnne

Guava的一个比较常见用法就是一个缓冲的用法,下面就是专门介绍这个缓存的具体用法。第一LoadingCache和CacheLoader的区别,前者是专门用来缓存的,后者是定义加载方式,而后者一般会有三种重载方法。

CacheLoader


CacheLoader baseLoader = new CacheLoader () { 
@Override 
public Object load(Object key) { 
loadCount.incrementAndGet(); 
return new Object(); 

@Override 
public ListenableFuture reload(Object key, Object oldValue) {
reloadCount.incrementAndGet();
return Futures.immediateFuture(new Object());
}
@Override
public Map loadAll(Iterable<? extends Object> keys) { 
loadAllCount.incrementAndGet(); 
return ImmutableMap.of(); 

};· 

在使用LoadingCache的builder里面可以放入,这个时候可以注意一下的是CacheLoader的第二个,这里的用法很奇特。


private static class QueuingExecutor implements Executor { 
private LinkedList tasks = Lists.newLinkedList(); 
@Override 
public void execute(Runnable task) { 
tasks.add(task); 

private void runNext() { 
tasks.removeFirst().run(); 


QueuingExecutor executor = new QueuingExecutor(); 
CacheLoader asyncReloader = 
CacheLoader.asyncReloading(baseLoader, executor); 

结合LoadingCache,这个是后没执行一次reload都会当做一个task,扔到QueuingExecutor的LinkedList里面,需要取得时候必须要使用:


executor.runNext(); 

才可以执行掉task的这个任务。

LoadingCache,刚刚讲解了和CacheLoader之间的关系,现在开始具体讲解使用方式。


LoadingCache cache = CacheBuilder.newBuilder() 
.recordStats() 
.build(cacheLoader); 

常见的声明就是这种方式,我们可以缓存的具体状态:


CacheStats stats = cache.stats(); 
stats.missCount();//没有命中的数量 
stats.loadSuccessCount();//加载成功数 
stats.loadExceptionCount();//加载异常 
stats.hitCount();//命中数 

获取key有两种方式get()/getUnchecked(), 其中一个的使用需要,不定义异常情况可以,但CacheLoader声明了检查型异常,就不可以调用getUnchecked(K)。
cache.get(key); 
cache.getUnchecked(key); 

猜你喜欢

转载自blog.csdn.net/jiangchunhui2009/article/details/86594495
今日推荐