Guava——Cache缓存工具

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alionsss/article/details/86762103

1. Cache缓存工具的特点

  • 自动加载对象至缓存
  • 达到最大size上限后,会根据LRU算法移除对象
  • 可通过最近读取或写对象的时长来移除对象
  • key自动使用弱引用包装
  • value自动使用弱引用or软引用包装
  • 对象移除后,会进行提示
  • 提供缓存访问的统计信息

2. 构建Cache

2.1 数据对象

public class MyData {

    private String name;

    private String info;

    public MyData(String name, String info) {
        this.name = name;
        this.info = info;
    }

}

2.2 数据获取层Dao

public class MyDao {

    /**
     * 获取数据需要花费一定时间
     *
     * @return 数据对象
     * @param key
     */
    public MyData getData(String key) {
        try {
            // 模拟获取的时间
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new MyData(key, "Hello World!" + key.hashCode());
    }

}

2.3 构建Cache对象(基于size)

// 数据获取层对象
MyDao myDao = new MyDao();

 // 移除数据的监听接口 lambda
RemovalListener<String, MyData> removalListener = notification -> System.out.println("remove -> " + notification);

 // 缓存加载器,当不存在对应缓存时,调用load()
CacheLoader<String, MyData> cacheLoader = new CacheLoader<String, MyData>() {
     public MyData load(String key) throws Exception {
         return myDao.getData();
     }
 };

 // 构建Cache
LoadingCache<String, MyData> cache = CacheBuilder.newBuilder()
         .maximumSize(100) // 设置缓存size上限,当达到最大size后,将删除最近最少使用的对象(即LRU算法)
         .expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存过期时间
         .removalListener(removalListener)
         .build(cacheLoader);

2.4 构建Cache对象(基于weight)

LoadingCache<String, MyData> cache = CacheBuilder.newBuilder()
        .maximumWeight(10000L) // 当所有对象的weight的和超过此值,就开始使用LRU策略移除对象
        .weigher(new Weigher<String, MyData>() {
            @Override
            public int weigh(String key, MyData value) {
            	// 设置对象占总weight的多少
            	// 例如你可以使用对象的内存大小,从而限制Cache最多占用的内存
                return key.length() + value.hashCode() % 100;
            }
        })
        .build(cacheLoader);

3. 使用Cache

3.1 从Cache中获取数据

MyData myData = cache.get("key");
System.out.println("myData = " + myData);

3.2 从Cache中获取数据(指定特定获取方式)

MyData myData = cache.get("key", new Callable<MyData>() {
	@Override
    public MyData call() throws Exception {
        Thread.sleep(5000); // 模拟获取花费的时间
        return new MyData("key", "Other Method");
    }
});
System.out.println("myData = " + myData);

3.3 删除某个key的缓存

cache.invalidate("key");

3.4 向Cache存入数据

cache.put("key", new MyData("key", "google"));

4. Cache的特性

4.1 缓存性能效果

for (int i = 0; i < 100; i++) {
try {
      // 前5个值获取比较慢,因为key都是新的,需要重新生成对象
      // 后续的数据,因为Cache中已有,所以很快
      String key = String.valueOf(i % 5);
      MyData myData = cache.get(key);
      System.out.println("myData = " + myData);
  } catch (ExecutionException e) {
      e.printStackTrace();
  }
}

4.2 缓存上限size

达到上限size后,会根据LRU策略移除缓存对象,并调用监听接口

Random random = new Random();
for (int i = 0; i < 100; i++) {
    try {
        String key = String.valueOf(random.nextInt(15));
        MyData myData = cache.get(key);
        System.out.println("myData = " + myData);
        System.out.println("cache.size() = " + cache.size());
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

4.3 缓存统计信息

// 构建Cache时,需要添加recordStats()
LoadingCache<String, MyData> cache = CacheBuilder.newBuilder()
        .maximumSize(10)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .removalListener(removalListener)
        .recordStats() // 启动统计
        .build(cacheLoader);
 
 Random random = new Random();
 for (int i = 0; i < 100; i++) {
    try {
         String key = String.valueOf(random.nextInt(15));
         MyData myData = cache.get(key);
         System.out.println("myData = " + myData);
     } catch (ExecutionException e) {
         e.printStackTrace();
     }
 }
// 打印统计信息
 System.out.println("stats = " + cache.stats());

猜你喜欢

转载自blog.csdn.net/alionsss/article/details/86762103