一.guava cache 介绍

  1.介绍 

     guava cache是Google guava中提供的一款轻量级的本地缓存组件,其特点是简单、轻便、完善、扩展性强,内存管理机制也相对完善。

  2.使用缓存的优点        

    1.减少了网络调用的开销
    2.减少了数据请求的序列化和反序列化

二.guava cache分类

  guava cache 提供了2种类型:
    Cache:创建1个缓存.
    LoadingCache:它能够通过CacheLoader自发的加载缓存,当获取缓存中数据不存在时,会通过CacheLoader的load方法自动加载到缓存中(后面会进步说明)

三.Cache的创建

  Guava的缓存有许多配置选项,所以为了简化缓存的创建过程,使用了Builder设计模式,而Builder使用的是链式编程的思想,也就是每次调用方法后返回的是对象本生,这样可以极大的简化配置过程。
  Guava的缓存创建需要通过CacheBuilder的build()方法构建,它的每个方法都返回CacheBuilder本身,直到build方法被调用才会创建Cache或者LoadingCache。

  创建过程(这里只做一个简单的创建,后面会加上各种配置项)

Cache<String, String> cache = CacheBuilder.newBuilder().build();
LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder().build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 缓存加载逻辑,可以通过查询数据库,获取经常访问且固定不变的数据
return null;
}
});
//LoadingCache在创建时需要我们添加一段缓存获取的逻辑,当我们从缓存中获取某个key对应的value时,如果缓存中没有,则会通过load(key)这个方法重新去加载这个value,当获取到value缓存并返回.

四.构建时缓存配置项的配置

  Cache和LoadingCache的配置项是一样的

 concurrencyLevel(int concurrencyLevel) : 设置并发级别
//cache提供了设置并发级别的api,使得缓存支持并发的写入和读取。同ConcurrentHashMap类似Guava cache的并发也是通过分离锁实现。在一般情况下,将并发级别设置为服务器cpu核心数是一个比较不错的选择。 initialCapacity(int initialCapacity):设置初始容量
//我们在构建缓存时可以为缓存设置一个合理大小初始容量。由于Guava的缓存使用了分离锁的机制,扩容的代价非常昂贵。所以合理的初始容量能够减少缓存容器的扩容次数。 maximumSize(long maximumSize):设置最大存储量
//Guava Cache可以在构建缓存对象时指定缓存所能够存储的最大记录数量。
//当Cache中的记录数量达到最大值后再调用put方法向其中添加对象,Guava会先从当前缓存的对象记录中选择一条删除掉,腾出空间后再将新的对象存储到Cache中。 expireAfterWrite(long duration, TimeUnit unit):设置写入多久的过期时间
expireAfterAccess(long duration, TimeUnit unit):设置多久没被访问(读/写)的过期时间
//在构建Cache对象时,可以通过CacheBuilder类的expireAfterAccess和expireAfterWrite两个方法为缓存中的对象指定过期时间,过期的对象将会被缓存自动删除。
//其中,expireAfterWrite方法指定对象被写入到缓存后多久过期,expireAfterAccess指定对象多久没有被访问后过期。
//可以同时用expireAfterAccess和expireAfterWrite方法指定过期时间,这时只要对象满足两者中的一个条件就会被自动过期删除。(有等验证)
       //一共4种,这里介绍2种,只不过是参数类型传的不同而已 removalListener(new RemovalListener<K, V>):设置移除监听器
//可以为Cache对象添加一个移除监听器,这样当有缓存被删除时可以感知到这个事件。在RemovalListener写的是删除回调时的通知逻辑 recordStats():打开统计信息开关
//可以对Cache的命中率、加载数据时间等信息进行统计。
//在构建Cache对象时,可以通过CacheBuilder的recordStats方法开启统计信息的开关。开关开启后Cache会自动对缓存的各种操作进行统计,调用Cache的stats方法可以查看统计后的信息。 weakKeys(): //使用弱引用存储键
weakValues()://使用弱引用存储值
softValues()://使用软引用存储值
//这里的配置项会在缓存回收处讲解

五.Cache的API操作

cache.asMap();                                     //将缓存转换成1个ConcurrentMap

cache.cleanUp(); //清空缓存

cache.get(K key, Callable<? extends V> loader) throws ExecutionException //获取缓存,当缓存不存在时,则通Callable进行加载并返回。该操作是原子,会抛出ExecutionException异常

cache.getAllPresent(Iterable<?> keys); //通过已存在的keys集合获取到一个固定长度的map集合

cache.getIfPresent(Object key); //获取一个缓存,如果该缓存不存在则返回一个null值

cache.invalidate(Object key); //通过key使value无效

cache.invalidateAll(); //使所有的value无效

cache.invalidateAll(Iterable<?> keys); //使keys集合中对应的value无效

cache.put(String key, Object value); //向缓存中添加数据

cache.putAll(Map<? extends K, ? extends V> m); //向级存中添加Map集合

cache.size(); //缓存大小

cache.stats(); //查看缓存命中结果

六.LoadingCache的API操作

loadingCache.getUnchecked(K key);                //不检查value是否存在

七.缓存的回收

  在前文提到过,在构建本地缓存时,我们应该指定一个最大容量来防止出现内存溢出的情况。在guava中除了提供基于数量和基于内存容量两种回收策略外,还提供了基于引用的回收。  

  1.基于数量的回收     

    这个回收策略非常简单,我们只需指定缓存的最大存储数量maximumSize即可:

CacheBuilder.newBuilder().maximumSize(100).build(); // 缓存数量上限为100 

  2.基于最大容量的回收

    在最大容量回收策略中,我们需要设置2个必要参数:
      maximumWeigh:用于指定最大容量
      Weigher:在加载缓存时用于计算缓存容量大小。
      这里我们例举一个key和value都是String类型缓存:

  CacheBuilder.newBuilder()
.maximumWeight(1024 * 1024 * 1024) // 设置最大容量为 1M
// 设置用来计算缓存容量的Weigher
.weigher(new Weigher<String, String>() {
@Override
public int weigh(String key, String value) {
return key.getBytes().length + value.getBytes().length;
}
}).build();
  //当缓存的最大数量/容量逼近或超过我们所设置的最大值时,Guava就会使用LRU算法对之前的缓存进行回收。

  3.基于引用的回收策略

    

强引用:
   强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。
   Object o=new Object(); // 强引用
   当内存空间不足,垃圾回收器不会自动回收一个被引用的强引用对象,而是会直接抛出OutOfMemoryError错误,使程序异常终止。 软引用:
   相对于强引用,软引用是一种不稳定的引用方式,如果一个对象具有软引用,当内存充足时,GC不会主动回收软引用对象,而当内存不足时软引用对象就会被回收。
   SoftReference<Object> softRef=new SoftReference<Object>(new Object()); // 软引用
   Object object = softRef.get(); // 获取软引用
   使用软引用能防止内存泄露,增强程序的健壮性。但是一定要做好null检测。 弱引用:
   弱引用是一种比软引用更不稳定的引用方式,因为无论内存是否充足,弱引用对象都有可能被回收。
   WeakReference<Object> weakRef = new WeakReference<Object>(new Object()); // 弱引用
   Object obj = weakRef.get(); // 获取弱引用  guava采用可以配置弱引用和软引用的策略来让用户自行决定缓存数据的类型,这样可以防止发生内存泄露的现象

八.代码实现

package com.study;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import org.junit.Test; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.google.common.cache.Cache;;
/**
* guava cache 测试
*
* @author pengbo.zhao
* @data 2019年11月5日 上午10:24:15
*
*
* cache的创建
*
* {@link #createCache()} 创建一个简单的cache
*
*
*
*/
public class GuavaCache { @Test
public void createCache() throws ExecutionException{
Cache<String,String> cache = CacheBuilder.newBuilder() //设置并发数(以获取当前操作系统cpu数来确定并发数)
.concurrencyLevel(Runtime.getRuntime().availableProcessors())
//设置初始容量
.initialCapacity(1000)
//设置最大存储量
.maximumSize(900)
//设置过期时间(3秒内没有使用)在指定时间内没有进行读写,会移除key,下次取的时候从loading中取
.expireAfterAccess(3,TimeUnit.SECONDS)
//设置过期时间(写入3秒内过期)在一定时间内没有创建/覆盖时,会移除key,下次从loading中取
.expireAfterWrite(3, TimeUnit.SECONDS)
//设置引用清除(设置弱引用存储值)
.weakValues()
//设置统计信息
.recordStats()
//设置移除通知
.removalListener(new RemovalListener<String, String>() {
@Override
public void onRemoval(RemovalNotification<String, String> notification) {
System.out.println(notification.getKey()+"-"+notification.getValue()+" is remove");
}
})
//构建
.build(); cache.put("key1", "value1");
System.out.println(cache.getIfPresent("key1"));
String key2 = cache.get("key2",new Callable<String>() {
@Override
public String call() throws Exception {
return "value2";
}
});
System.out.println(key2);
}
}
是在指定项在一定时间内没有创建/覆盖时,会移除该key,下次取的时候从loading中取

Guava 工具类之Cache的使用的更多相关文章

  1. 强大的 Guava 工具类

    Java 开发的同学应该都使用或者听说过 Google 提供的 Guava 工具包.日常使用最多的肯定是集合相关的工具类,还有 Guava cache,除了这些之外 Guava 还提供了很多有用的功能 ...

  2. 工具篇:介绍几个好用的guava工具类

    前言 平时我们都会封装一些处理缓存或其他的小工具.但每个人都封装一次,重复造轮子,有点费时间.有没有一些好的工具库推荐-guava.guava是谷歌基于java封装好的开源库,它的性能.实用性,比我们 ...

  3. Google guava工具类的介绍和使用

    概述 工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率.谷歌作为大公司,当然会从日常的工作中提取中很多高效率的方法出来.所以就诞生了guava.. 高效设计良好的API ...

  4. Google的Guava工具类splitter和apache stringutil对比 编辑

    一直用的是apache的stringutil工具类,其实google的工具类项目 guava中居然也有字符串的分隔类splitter的,在 http://code.google.com/p/guava ...

  5. Guava工具类

    原文链接:http://blog.csdn.net/mnmlist/article/details/53425865 Objects类 Objects类有几个比较不错的方法,toString.hash ...

  6. Guava工具类学习

    目录 一.介绍 二.Optional类 1.定义 2.java8自带Optional 3.使用 三.Preconditions类 1.定义 2.使用 四.Ordering类 1.定义 2.使用 五.R ...

  7. Guava 工具类之 Splitter的使用

    Splitter可以对字符串进行分割,在分割时的方式有2种, 1.按字符/字符串分割 2.按正则进行分割 Splitter在分割完成时可以转换成list和map 一.按字符进行分割 //1.用指定字符 ...

  8. Guava 工具类之joiner的使用

    joiner主要用于对字符串的连接,也可用于对map中key value的连接 public class JoinerTest { private static final List<Strin ...

  9. Guava 工具类之Strings 的使用

    public class StringTest { public static void main(String[] args) { //判断是null还是空字符串 boolean b1 = Stri ...

随机推荐

  1. JSP简单标签的开发

    1. 新建RepeatSampleTag类,代码如下: package bid.zhazhapan.fims.tag; import java.io.IOException; import java. ...

  2. std_msgs/String.msg

    from std_msgs.msg import String http://docs.ros.org/api/std_msgs/html/msg/String.html

  3. 发布自己的类库包到Nuget

    今天来记录下发布自己的类库到Nuget. 一.准备工作 注册www.nuget.org,获取APIKey 后面发布要使用到. 二.创建项目 新建类库项目 新建测试demo类 public class ...

  4. 【随记】Sql Server 2008 R2 备份时“无法打开备份设备”

    如下图所示,在执行SQL一个简单的备份命令时发生下面的错误 可能的原因: 1.文件夹权限问题: 2.Sql Server SQLServer服务器用户策略问题: 问题排查: 1.查看了temp文件夹, ...

  5. Vue.js中 watch的理解以及深度监听

    如代码: <div> <p>FullName: {{fullName}}</p> <p>FirstName: <input type=" ...

  6. python技巧获取26个英语字母

    import string string.ascii_uppercase # 获取26个大写字母 string.ascii_lowercase # 获取26个小写字母 string.ascii_let ...

  7. Spring boot 去除URL 里的 JSESSIONID

    方法一 application.yml 里设置 server: port: 80 servlet: session: tracking-modes: cookie cookie: http-only: ...

  8. centos7使用MariaDB(转)

    转载文章:https://blog.csdn.net/zwkkkk1/article/details/78444581?locationNum=10&fps=1 最近使用centos7,php ...

  9. CMU Database Systems - Timestamp Ordering Concurrency Control

    2PL是悲观锁,Pessimistic,这章讲乐观锁,Optimistic,单机的,非分布式的 Timestamp Ordering,以时间为序,这个是非常自然的想法,按每个transaction的时 ...

  10. Nginx http -> https 跳转后 POST 丢失

    在 nginx.conf 配置文件中添加如下配置进行 http -> https 跳转 server { listen ; server_name example.org; https://$s ...