【guava】cache
Cache
public class Solution { public static void main(String... arg) { //cache Cache<String, String> cacher = CacheBuilder.newBuilder() .maximumSize(1) .weakValues()//弱引用 .expireAfterWrite(5, TimeUnit.SECONDS)//写过期 //.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期 .recordStats() .removalListener(new RemovalListener<String, String>() { @Override public void onRemoval(RemovalNotification<String, String> removalNotification) { System.out.println("remove: " + removalNotification.getKey() + "-" + removalNotification.getValue()); } }) .build(); //value = null 会抛异常 cacher.put("key1", "value"); //获取缓存value System.out.println(cacher.getIfPresent("key1")); //如没有, 起线程去查询 //如有并发冲突,只会起一个线程 !!! try { String value2 = cacher.get("key2", new Callable<String>() { /** * value == null, 抛异常 */ @Override public String call() throws Exception { return "value"; } }); System.out.println(value2); } catch (ExecutionException e) { e.printStackTrace(); } //缓存失效 cacher.invalidate("key1"); cacher.invalidateAll(Lists.newArrayList("key1", "key2")); cacher.invalidateAll(); //打印日志 System.out.println(cacher.stats()); } }
LoadingCache
cache的子类。需要实现CacheLoader
public class Solution {
public static void main(String... arg) {
//1、cache
LoadingCache<String, String> cacher = CacheBuilder.newBuilder()
.maximumSize(10)
.expireAfterWrite(1800, TimeUnit.SECONDS)//写过期
//.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期
.recordStats()
.build(new CacheLoader<String, String>() {
/**
* 2、
* cache.get, cache.getUnchecked 会调用此方法
* 并发冲突时,只会调用一次
*/
@Override
public String load(String s) throws Exception {
System.out.println("load: " + s);
return "value";
}
/**
* 3、
* cache.getAll会调用此方法
* 只会load未命中的key
*/
@Override
public Map<String, String> loadAll(
final Iterable<? extends String> ids)
throws Exception {
System.out.println("loadAll: " + StringUtils.join(ids, "-"));
Map<String, String> map = Maps.newHashMap();
ids.forEach(id -> map.put(id, "value"));
return map;
}
});
//4、如没有则调用CacheLoader load方法
//5、getUnchecked 与 get的区别在于 抛出unchecked异常
cacher.getUnchecked("key1");
try {
cacher.get("key1");
} catch (ExecutionException e) {
e.printStackTrace();
}
//6、批量查询。查询多个key, 每个key 执行一次load方法
try {
cacher.getAll(Lists.newArrayList("key1", "key2", "key3")).forEach((k, v) -> {
System.out.println(k + "-" + v);
});
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
搭配Optional使用(避免value为空的情况)
public class Solution { public static void main(String... arg) { //cache Cache<String, Optional<String>> cacher = CacheBuilder.newBuilder() .maximumSize(1) .weakValues()//弱引用 .expireAfterWrite(5, TimeUnit.SECONDS)//写过期 //.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期 .recordStats() .build(); try { Optional<String> valueOpt = cacher.get("key1", new Callable<Optional<String>>() { @Override public Optional<String> call() throws Exception { return Optional.empty(); } }); cacher.getIfPresent("key1") .ifPresentOrElse(v -> System.out.println("return " + v) , () -> System.out.println("return null")); } catch (ExecutionException e) { e.printStackTrace(); } } }

浙公网安备 33010602011771号