Guava Cache有一些优点如下 :
1. 线程安全的缓存, 与ConcurrentMap相似(前者更"好"), 在高并发情况下、能够正常缓存更新以及返回.
2. 提供了三种基本的缓存回收方式 : 基于容量回收
、定时回收
和基于引用回收
(本文没有提及引用回收).
3. 提供了两种定时回收:按照写入时间, 最早写入的最先回收;按照访问时间,最早访问的最早回收.
4. 可以监控缓存加载/命中情况.
5. 使用方便、简单.
1. 最基础的例子[CacheBuilder]
// 新建CacheBuilder
Cache<Integer, String> cache = CacheBuilder.newBuilder().build();
cache.put(1, "a");
cache.put(2, "b");
System.out.println(cache.getIfPresent(1)); // 输出: a
System.out.println(cache.getIfPresent(3)); // 输出: null
System.out.println(cache.getAllPresent(new ArrayList<Integer>(){{
add(1);
add(2);
}})); // 输出: {1=a, 2=b}
2. 若无缓存时,自定义缓存值[CacheLoader、get()]
// 遇到不存在的key,定义默认缓存值
// 1. 在cache定义时设置通用缓存模版
LoadingCache<Integer, String> cache1 = CacheBuilder.newBuilder().build(
new CacheLoader<Integer, String>() {
@Override
public String load(Integer key) throws Exception {
return "hellokey" + key;
}
}
);
cache1.put(1, "a");
System.out.println(cache1.getIfPresent(1)); // 输出: a
try {
System.out.println(cache1.getAll(new ArrayList<Integer>(){{ // getAll()将没有命中的key调用load()方法去加载数据
add(1);
add(2);
}})); // 输出: {1=a, 2=hellokey2}
System.out.println(cache1.get(3)); // 输出: hellokey3
} catch (ExecutionException e) {
e.printStackTrace();
}
// 2. 在获取缓存值时设置缓存
Cache<Integer, String> cache2 = CacheBuilder.newBuilder().build();
cache2.put(1, "a");
System.out.println(cache2.getIfPresent(1)); // 输出: a
try {
String value = cache2.get(2, () -> "hellokey2");
System.out.println(value); // 输出: hellokey2
} catch (ExecutionException e) {
e.printStackTrace();
}
3. 控制缓存的大小/多少[.maximumSize()、.maximumWeight()]
// ps. .maximumSize(long),.maximumWeight(long)互斥,build()只可以二选一
// 1. 基于缓存多少
Cache<Integer, String> cache1 = CacheBuilder.newBuilder()
.maximumSize(2L) // 设置缓存上限,最多两个
.build();
cache1.put(1, "a");
cache1.put(2, "b");
cache1.put(3, "c");
System.out.println(cache1.asMap()); // 输出: {3=c, 2=b}
System.out.println(cache1.getIfPresent(2)); // 输出: b
cache1.put(4, "d");
System.out.println(cache1.asMap()); // 输出: {2=b, 4=d}
// 2. 基于缓存大小
Cache<Integer, Integer> cache2 = CacheBuilder.newBuilder()
.maximumWeight(100L) // 指定最大总重
.weigher((Weigher<Integer, Integer>) (key, value) -> {
if (value % 2 == 0) {
return 20; // 偶数,则权重为20
} else {
return 5; // 非偶数,则权重为5
}
}) // 设置权重函数
.build();
for (int i = 0; i <= 20; i += 2) {
cache2.put(i, i);
}
System.out.println(cache2.asMap()); // 输出: {20=20, 18=18, 16=16, 14=14}
cache2.invalidateAll(); // 清除所有的缓存
for (int i = 0; i <= 20; i += 1) {
cache2.put(i, i);
}
System.out.println(cache2.asMap()); // 输出: {20=