Guava Cache缓存的移除与读取

news/2024/7/6 0:40:24

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 

1、通过put或putAll手动向Cache中添加数据,guava不缓存value是null的key。我们可以在系统启动的时候,就将某些数据手动放入缓存中,这样就可以避免系统启动后,第一个用户访问缓存不能命中的情况。

public static void testPut() {  Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(3).recordStats().build();  // 通过put或者putAll手动将数据添加到缓存  cache.put("id", "10");  Map<String, String> batch = new HashMap<>();  cache.put("name", "aty");  cache.put("addr", "sz");  cache.putAll(batch);  // 数量超出最大限制,会导致guava清除之前的数据,evictionCount增加1  // 手动添加缓存数据,不会影响其他缓存统计指标值  cache.put("new", "replace");  System.out.println(cache.stats());  // 不接受null  try {  cache.put("a", null);  } catch (NullPointerException e) {  }  
}  

2、通过getIfPresent/getAllPresent/get读取缓存中的数据。

public static void testGet() throws Exception {  Cache<String, String> cache = CacheBuilder.newBuilder().recordStats().build();  cache.put("name", "aty");  // 缓存未命中missCount加1  System.out.println(cache.getIfPresent("s") == null);  System.out.println(cache.stats());  // 缓存命中hitCount加1  System.out.println(cache.getIfPresent("name") != null);  System.out.println(cache.stats());  // Callable.call()不能返回null,否则guava报异常  Callable<String> callable = new Callable<String>() {  @Override  public String call() throws Exception {  Thread.sleep(2000);  return "demo";  }  };  // 使用guava Stopwatch计时  Stopwatch watch = Stopwatch.createStarted();  cache.get("a", callable);  watch.stop();  // 缓存不存在missCount加1,调用时间也会增加到totalLoadTime  System.out.println(cache.stats());  // 大致2s 可以证明: guava cache是在调用者的线程中执行callable任务的  System.out.println("elapse time=" + watch.elapsed(TimeUnit.MILLISECONDS));  
}  


3、如果明确知道某些缓存无用,我们可以通过invalidate/invalidateAll删除

public static void testDelete() {  Cache<String, String> cache = CacheBuilder.newBuilder().recordStats().build();  cache.put("a", "aty");  cache.put("b", "aty");  cache.put("c", "aty");  cache.put("d", "aty");  // 单个删除  cache.invalidate("a");  System.out.println(cache.stats());  System.out.println(cache.size()); // 3  // 批量删除  cache.invalidateAll(Arrays.asList("b", "c"));  System.out.println(cache.stats());  System.out.println(cache.size()); // 1  // 清除所有  cache.invalidateAll();  System.out.println(cache.stats());  System.out.println(cache.size()); // 0  
}  

4、通过调用cleanUp执行缓存清理操作,比如删除过期的key。

public static void testCleanup() throws Exception {  Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();  cache.put("a", "a");  // 睡眠2s让缓存过期  Thread.sleep(2000);  System.out.println(cache.size()); // 缓存大小仍然是1,因为调用这个方法不会触发缓存清除  System.out.println(cache.getIfPresent("a") == null);// 调用get/put会触发缓存清除  Cache<String, String> cache2 = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();  cache2.put("a", "a");  // 睡眠2s让缓存过期  Thread.sleep(2000);  cache2.cleanUp();// 手动触发缓存清除动作  System.out.println(cache2.size()); // 0  
}  


5、通过asMap可以拿到Cache底层使用的数据接口,通过这个map也可以添加或删除cache中的数据。通过map获取数据,不会影响缓存统计;通过map添加数据,可能会影响evictionCount。虽然可以对这个map进行迭代,不过有可能会出现获取到值是null的情况。

public static void testAsMap() throws Exception {  Cache<String, String> cache = CacheBuilder.newBuilder().build();  cache.put("a", "a");  cache.put("b", "b");  cache.put("c", "c");  // 通过底层map得到iterator,以便后面遍历  Iterator<String> iterator = cache.asMap().keySet().iterator();  // 1.启动一个线程进入睡眠状态  Thread thread = new Thread(new Runnable() {  @Override  public void run() {  try {  Thread.sleep(60 * 60 * 1000);  } catch (InterruptedException e) {  cache.invalidate("b");  }  }  });  thread.start();  while (iterator.hasNext()) {  String key = iterator.next();  if (key.equals("b")) {  thread.interrupt(); // 唤醒睡眠的线程,模拟线程的交替执行  Thread.sleep(100); // 让唤醒的线程执行完(清除缓存数据)  }  System.out.println("key=" + key + ",value=" + cache.getIfPresent(key));  }  } 

 

转载于:https://my.oschina.net/u/2391658/blog/907565


http://lihuaxi.xjx100.cn/news/242025.html

相关文章

运用面向对象原则,设计一款音乐点唱机

2019独角兽企业重金招聘Python工程师标准>>> &#xff0e;设计内容及要求 能够实现简单的音乐播放器功能&#xff0c;如&#xff1a;打开本地文件&#xff0c;播放&#xff0c;暂停&#xff0c;停止&#xff0c;背景播放&#xff0c;单曲循环等等&#xff0c;界面充…

UI设计培训教程分享:UI设计师的色彩使用技巧

作为一名合格的UI设计师&#xff0c;色彩的使用是非常重要的&#xff0c;一个专业的UI设计师对于UI设计色彩的搭配是非常的出色的&#xff0c;下面小编就为大家分享UI设计培训教程&#xff1a;UI设计师的色彩使用技巧 UI设计培训教程分享&#xff1a;UI设计师的色彩使用技巧 一…

powerdesigner类图在子类中显示从父类继承来的方法

首先确保画了子类和父类之间的继承线 然后在子类的选项卡中点击

女生参加web前端培训压力大吗

女生参加web前端培训压力大吗?这个问题很多人都是想知道的&#xff0c;因为对于互联网行业来说&#xff0c;大部分都是男性&#xff0c;尤其是技术岗位&#xff0c;女生做前端压力大小和能力也有很大的关系&#xff0c;前端技术好工作效率高&#xff0c;那么压力相对较低。 女…

Linux下用于查看系统当前登录用户信息的4种方法

作为系统管理员&#xff0c;你可能经常会&#xff08;在某个时候&#xff09;需要查看系统中有哪些用户正在活动。有些时候&#xff0c;你甚至需要知道他&#xff08;她&#xff09;们正在做什么。本文为我们总结了4种查看系统用户信息&#xff08;通过编号&#xff08;ID&…

Python培训教程分享:“高效实用” 的Python工具库

作为一名合格Python技术员&#xff0c;对于Python工具库的使用是少不了的&#xff0c;本期Python培训教程就为大家分享的是““高效实用” 的Python工具库”&#xff0c;希望能够帮助到大家。 Python培训教程分享&#xff1a;“高效实用” 的Python工具库&#xff1a; 1、Reque…

postfix+mysql 发件服务

1.配置mysql*实验之前&#xff0c;制作要使用数据库和表*添加数据库用户&#xff0c;并给其授权* vim /etc/postfix/mailuser.cf ##查询用户名1 host localhost ##数据库主机2 user postuser ##登录数据库用户3 password 123 ##登录密码4 dbname email ##p…