MapMaker作为大多数基本缓存功能地提供者。
ConcurrentMap<String,Book> books = new MapMaker().concurrencyLevel(2) //并发级别,即允许最多2个线程并发更新, 默认值为4 .softValues() //使用SoftReference引用对象包装value .makeMap(); //构建Map对象
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是Cache的扩展类,具有自加载功能。
基本操作。
Book book = loadingCache.get(id); //获取key为id的缓存 ImmutableMap<key,value> map = cache.getAll(Iterable<? Extends key>); //获取多个key的缓存,并返回不可变map对象 refresh(key); //刷新key对应的缓存
CacheBuilder通过构建器模式构建Cache和LoadingCache实例。
构建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可以用于构建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
//用Function构建CacheLoader, 将输入转换成输出 CacheLoader<Key,value> cacheLoader = CacheLoader.from(Function<Key,Value> func); //通过Supplier构建CacheLoader CacheLoader<Object,Value> cacheLoader = CacheLoader.from(Supplier<Value> supplier);
用于收集一些缓存信息。
LoadingCache<String,TradeAccount> tradeAccountCache = CacheBuilder.newBuilder().recordStats() //开启记录状态
获取CacheStat对象
CacheStats cacheStats = cache.stats();
通过CacheStat可以获取的信息
1.加载新值消耗的平均时间 2.命中次数 3.未命中次数 ...
用于监听Cache中的key被移除时。
用于接收触发RemovalListener的onRemoval的参数传入,可获取对应key,value等。
通过RemovalNotification.getCause()还可以知道该对象被移除的原因.
public enum RemovalCause { //用户手动移除 EXPLICIT, //用户手动替换 REPLACED, //被垃圾回收 COLLECTED, //超时过期 EXPIRED, //由于缓存大小限制 SIZE; }
我们可以异步执行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之前。