文档章节

走近Guava(五): 缓存

ihaolin
 ihaolin
发布于 2014/04/05 14:49
字数 968
阅读 8035
收藏 16

缓存:

MapMaker类

  • MapMaker作为大多数基本缓存功能地提供者。
ConcurrentMap<String,Book> books = new MapMaker().concurrencyLevel(2) //并发级别,即允许最多2个线程并发更新, 默认值为4
                                                 .softValues() //使用SoftReference引用对象包装value
                                                 .makeMap(); //构建Map对象

Guava缓存:

Cache类:

  • 基本操作
put(key,value); //存放key-value
V value = cache.get(key, Callable<? Extends V> value); //获取key对应的缓存对象,不存在或调用Callable实例的call方法来返回key对应的值
上面的cache.get有效代替了我们通常的操作:
value = cache.get(key);
   if(value == null){
       value = someService.retrieveValue();
       cache.put(key,value);
   }
上面通过Callable获取值是一个异步过程,我们也可以通过非异步来获取值:
cache.get(key,Callables.returning(someService.retrieveValue()); //同步方式获取不存在的key缓存
同样我们也可以使缓存的数据失效:
invalidate(key) //废弃key对应的缓存
invalidateAll() //废弃所有的缓存
invalidateAll(Iterable<?> keys) //废弃keys对应的缓存

LoadingCache类:

  • LoadingCache是Cache的扩展类,具有自加载功能。
  • 基本操作。
Book book = loadingCache.get(id); //获取key为id的缓存
ImmutableMap<key,value> map = cache.getAll(Iterable<? Extends key>); //获取多个key的缓存,并返回不可变map对象
refresh(key); //刷新key对应的缓存

CacheBuilder类:

  • CacheBuilder通过构建器模式构建CacheLoadingCache实例。
  • 构建LoadingCache对象实例一。
LoadingCache<String, TradeAccount> traLoadingCache =
				CacheBuilder.newBuilder()
					.expireAfterAccess(5L, TimeUnit.MINUTES) //5分钟后缓存失效
					.maximumSize(5000L) //最大缓存5000个对象
					.removalListener(new TradeAccountRemovalListener()) //注册缓存对象移除监听器
					.ticker(Ticker.systemTicker()) //定义缓存对象失效的时间精度为纳秒级
					.build(new CacheLoader<String, TradeAccount>(){ 
						@Override
						public TradeAccount load(String key) throws Exception {
							// load a new TradeAccount not exists in cache
							return null;
						}
					});
  • 通过SoftReference对象实现自动回收
LoadingCache<String, TradeAccount> traLoadingCache =
				CacheBuilder.newBuilder()
					.expireAfterAccess(5L, TimeUnit.MINUTES) //5分钟后缓存失效
					.softValues() //使用SoftReference对象封装value, 使得内存不足时,自动回收
					.removalListener(new TradeAccountRemovalListener()) //注册缓存对象移除监听器
					.ticker(Ticker.systemTicker()) //定义缓存对象失效的时间精度为纳秒级
					.build(new CacheLoader<String, TradeAccount>(){ 
						@Override
						public TradeAccount load(String key) throws Exception {
							// load a new TradeAccount not exists in cache
							return null;
						}
					});
  • 构建一个可自动刷新缓存的LoadingCache
LoadingCache<String, TradeAccount> traLoadingCache =
				CacheBuilder.newBuilder()
					.concurrencyLevel(10) //允许同时最多10个线程并发修改
					.refreshAfterWrite(5L, TimeUnit.SECONDS) //5秒中后自动刷新
					.removalListener(new TradeAccountRemovalListener()) //注册缓存对象移除监听器
					.ticker(Ticker.systemTicker()) //定义缓存对象失效的时间精度为纳秒级
					.build(new CacheLoader<String, TradeAccount>(){ 
						@Override
						public TradeAccount load(String key) throws Exception {
							// load a new TradeAccount not exists in cache
							return null;
						}
					});

CacheBuilderSpec:

  • CacheBuilderSpec可以用于构建CacheBuilder时的配置描述。
String configString = "concurrencyLevel=10,refreshAfterWrite=5s"
  • 通过CacheBuilderSpec构建LoadingCache:
String spec = "concurrencyLevel=10,expireAfterAccess=5m,softValues";
CacheBuilderSpec cacheBuilderSpec = CacheBuilderSpec.parse(spec);
CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.from(cacheBuilderSpec);
LoadingCache<String, TradeAccount> traLoadingCache = cacheBuilder
		.ticker(Ticker.systemTicker())
		.removalListener(new TradeAccountRemovalListener())
		.build(new CacheLoader<String, TradeAccount>(){ 
			@Override
			public TradeAccount load(String key) throws Exception {
				// load a new TradeAccount not exists in cache
				return null;
			}
});

CacheLoader类:

  • 构建CacheLoader
//用Function构建CacheLoader, 将输入转换成输出
CacheLoader<Key,value> cacheLoader = CacheLoader.from(Function<Key,Value> func);
//通过Supplier构建CacheLoader
CacheLoader<Object,Value> cacheLoader = CacheLoader.from(Supplier<Value> supplier);

CacheStats类:

  • 用于收集一些缓存信息。
LoadingCache<String,TradeAccount> tradeAccountCache = CacheBuilder.newBuilder().recordStats() //开启记录状态
  • 获取CacheStat对象
CacheStats cacheStats = cache.stats();
  • 通过CacheStat可以获取的信息
1.加载新值消耗的平均时间
2.命中次数
3.未命中次数
...

RemovalListener类:

  • 用于监听Cache中的key被移除时。

RemovalNotification类:

  • 用于接收触发RemovalListener的onRemoval的参数传入,可获取对应key,value等。
  • 通过RemovalNotification.getCause()还可以知道该对象被移除的原因.
public enum RemovalCause {
  //用户手动移除
  EXPLICIT,
  //用户手动替换
  REPLACED,
  //被垃圾回收
  COLLECTED,
  //超时过期
  EXPIRED,
  //由于缓存大小限制
  SIZE;
}

RemovalListeners类:

  • 我们可以异步执行RemovalListener的onRemoval触发动作
RemovalListener<String,TradeAccount> myRemovalListener = new RemovalListener<String, TradeAccount>() {
           @Override
           public void onRemoval(RemovalNotification<String,TradeAccount> notification) {
               //Do something here
           }
       };
RemovalListener<String,TradeAccount> removalListener =
                        RemovalListeners.asynchronous(myRemovalListener,executorService);

上面的步骤必须在我们注册RemovalListener到 CacheBuilder之前

不吝指正。

© 著作权归作者所有

ihaolin

ihaolin

粉丝 263
博文 164
码字总数 106524
作品 4
朝阳
高级程序员
私信 提问
加载中

评论(2)

董严
董严
refreshAfterWrite ,本该5s后自动刷新(调用load),但是没有调用,为什么?
比计划多一点
比计划多一点
挺好,不过能给出最佳实践就好了
Guava库学习:学习Guava Cache知识汇总

原文地址:Guava库学习:学习Guava Cache知识汇总 至此,我们结束了对Guava Cache 缓存机制的学习,在学习过程中,我们学习了如何简单的通过MapMaker创建最简单的ConcurrentMap缓存,我们也了...

Realfighter
2014/12/21
1K
1
Guava库学习:学习Guava Cache(六)CacheStats

原文地址:Guava库学习:学习Guava Cache(六)CacheStats 上一篇,Guava库学习:学习Guava Cache(五)CacheLoader 中, 我们学习了CacheLoader抽象类,主要是其中的from方法,接收一个Fun...

Realfighter
2014/12/09
1K
0
Google的Guava类库简介(转)

说明:信息虽然有点旧,至少可以先了解个大概。 Guava是一个Google的基于Java的类库集合的扩展项目,包括collections, caching, primitives support, concurrency libraries, common annotat...

easonjim
2017/11/01
0
0
Guava学习笔记:Google Guava 类库简介

Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这......

长平狐
2013/06/17
1K
0
Google Guava 类库简介(1)

Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这......

十二缸帕萨特
2015/10/07
84
0

没有更多内容

加载失败,请刷新页面

加载更多

DDD(十)--仓储

1、引言 DDD中的Repository(仓储):协调领域和数据映射层,利用类似与集合的接口来访问领域对象。——《领域驱动设计-软件核心复杂性应对之道》 仓储是DDD中产生的概念,也就是说,如果应...

MrYuZixian
10分钟前
5
0
Jenkins的多种迁移方法

说明 Jenkins有时需要进行迁移,主目录会发生改变,本文主要讲解如何更改主目录。由于jenkins安装方式的不同,主目录也不一样。 本测试环境:Centos7.6 X64。注意:在更改主目录之前,请一定...

Elson
11分钟前
5
0
好程序员web前端教程分享前端javascript练习题三

好程序员web前端教程分享前端javascript练习题三,cookie 一周内免登录 样式代码: <form action=""> 姓名:<input type="text" id="usename"/><br /> 密码:<input type="text" i="mima"/>......

好程序员官网
30分钟前
5
0
Table 信息转成pojo属性

import com.google.common.base.CaseFormat;import java.sql.*;/** * @author: liyhu * @date: 2019/11/22 */public class TableToPojo { static String url="jdbc:mys......

暗中观察
今天
8
0
Access数据库-C#操作类

//Access数据库-C# 操作类 代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.OleDb;using System.Data;namespace XXX{......

芳缘
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部