guavacache mysql_Guava Cache缓存的移除与读取

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

public static void testPut() {

Cache cache = CacheBuilder.newBuilder().maximumSize(3).recordStats().build();

// 通过put或者putAll手动将数据添加到缓存

cache.put("id", "10");

Map 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 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 callable = new Callable() {

@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 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 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 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 cache = CacheBuilder.newBuilder().build();

cache.put("a", "a");

cache.put("b", "b");

cache.put("c", "c");

// 通过底层map得到iterator,以便后面遍历

Iterator 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));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值