import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
public class GuavaCache {
public static void main(String[] args) throws InterruptedException, ExecutionException {
loadingCacheTest();
}
//LoadingCache
private static void loadingCacheTest() throws ExecutionException {
CacheLoader loader = new CacheLoader(){
@Override
public String load(String key) throws Exception {
Thread.sleep(1000);
System.out.println(key + " is loaded from a cacheLoader!");
return key+"'s value";
}
};
LoadingCache loadingCache = CacheBuilder.newBuilder().maximumSize(3).build(loader);
loadingCache.get("k1");
loadingCache.get("k2");
loadingCache.get("k3");
loadingCache.get("k1");
loadingCache.get("k4");
}
//统计信息
private static void recordStatsTest() {
Cache cache = CacheBuilder.newBuilder().maximumSize(3).recordStats().build();//开启统计信息开关
cache.put("k1", "value");
cache.put("k2", "value");
cache.put("k3", "value");
cache.put("k4", "value");
cache.getIfPresent("k1");
cache.getIfPresent("k2");
cache.getIfPresent("k3");
cache.getIfPresent("k4");
cache.getIfPresent("k5");
cache.getIfPresent("k6");
System.out.println(cache.stats());
}
//自动加载,如果值没有缓存,则根据callable进行加载,并将返回值加入缓存;
//如果同时有多个请求相同的key,则guava会保证只有一个callable进行加载
private static void autoCacheTest() {
Cache cache = CacheBuilder.newBuilder().build();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread1");
try {
String value = cache.get("key", new Callable() {
@Override
public String call() throws Exception {
System.out.println("load by thread1...");
Thread.sleep(1000);//模拟加载
return "auto load by callable 1";
}
});
System.out.println("thread1 "+value);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread2");
try {
String value = cache.get("key", new Callable() {
@Override
public String call() throws Exception {
System.out.println("load by thread2...");
Thread.sleep(1000);//模拟加载
return "auto load by callable 2";
}
});
System.out.println("thread2 "+value);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
}
// 移除监听器
private static void removalListenerTest() {
RemovalListener listener = new RemovalListener(){
@Override
public void onRemoval(RemovalNotification notification) {
System.out.println("[" + notification.getKey() +":" + notification.getValue() + "] is removed!");
}
};
Cache cache = CacheBuilder.newBuilder().maximumSize(3).removalListener(listener).build();
cache.put("k1", "a");
cache.put("k2", "a");
cache.put("k3", "a");
cache.put("k4", "a");
cache.put("k5", "a");
}
// 手动清除
private static void invalidateTest() {
Cache cache = CacheBuilder.newBuilder().build();
Object value = new Object();
cache.put("k1", "value1");
cache.put("k2", "value2");
cache.put("k3", "value3");
cache.put("k4", "value4");
List list = new ArrayList();
list.add("k1");
list.add("k2");
cache.invalidateAll(list);
System.out.println(cache.getIfPresent("k1"));
System.out.println(cache.getIfPresent("k2"));
System.out.println(cache.getIfPresent("k3"));
System.out.println(cache.getIfPresent("k4"));
cache.invalidate("k3");
System.out.println(cache.getIfPresent("k3"));
cache.invalidateAll();
System.out.println(cache.getIfPresent("k4"));
}
private static void basicUsage() {
Cache cache = CacheBuilder.newBuilder().build();
cache.put("word", "Hello Guava Cache");
System.out.println(cache.getIfPresent("word"));
}
//设置最大存储
private static void maximumSizeTest() {
Cache cache = CacheBuilder.newBuilder().maximumSize(2).build();
cache.put("k1", "a");
cache.put("k2", "b");
cache.put("k3", "c");
System.out.println("第一个值:"+cache.getIfPresent("k1"));
System.out.println("第二个值:"+cache.getIfPresent("k2"));
System.out.println("第三个值:"+cache.getIfPresent("k3"));
}
//设置过期时间,按最后写时间开始计时
private static void expireAfterWriteTest() throws InterruptedException {
Cache cache = CacheBuilder.newBuilder().expireAfterWrite(3, TimeUnit.SECONDS).build();
cache.put("k1", "a");
int times=1;
while(true) {
System.out.println("第"+ times++ + "次获取到的值为:"+cache.getIfPresent("k1"));
Thread.sleep(1000);
}
}
//设置过期时间, 按最后一次读开始计时
private static void expireAfterAccessTest() throws InterruptedException {
Cache cache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.SECONDS).build();
cache.put("k1", "a");
int times=1;
while(true) {
Thread.sleep(times*1000);
System.out.println("等待"+times+++"s后取到k1的值为:"+cache.getIfPresent("k1"));
}
}
//弱引用
private static void weakValueTest() {
Cache cache = CacheBuilder.newBuilder().weakValues().build();
Object value = new Object();
cache.put("k1", value);
value = new Object();
System.gc();
System.out.println(cache.getIfPresent("k1"));
}
}
参考资料
- https://segmentfault.com/a/1190000011105644