LoadingCache可替换Map作为系统的缓存,相比于Map提供了数据自动回收功能,当然还有诸如数据删除监听、数据更新等功能,具体使用方式见代码与注释:
package com.zte.sunquan.demo.test;
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.RemovalListeners;
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Lists;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by sunquan on 2017/11/20.
*/
public class H2Test {
//simulate data
List list = Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m");
private String compute(Integer key) {
System.out.println(Thread.currentThread().getName() + "-compute value with " + key);
return list.get(key);
}
@Test
public void testCache1() throws ExecutionException {
Cache cache = CacheBuilder.newBuilder().build();
cache.put(0, "a");
cache.put(1, "b");
cache.put(2, "c");
cache.put(3, "d");
System.out.println(cache.getIfPresent(0));//a
System.out.println(cache.getIfPresent(-1));//null
System.out.println(cache.get(-1, () -> "bb"));//bb (无指定key的value,则执行callable,并将计算值加入缓存)
System.out.println(cache.getIfPresent(-1));//bb
}
@Test
public void testCache3() throws ExecutionException, InterruptedException {
LoadingCache cache = CacheBuilder.newBuilder()
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔1秒进行数据更新,会执行compute重新计算
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
System.out.println("v1:" + cache.get(1));
cache.invalidate(1);//消除key为1的缓存
Thread.sleep(2000);
System.out.println("v2:" + cache.get(1));//重新执行compute
}
@Test
public void testCache2() throws ExecutionException, InterruptedException {
LoadingCache cache = CacheBuilder.newBuilder()
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔1秒进行数据更新,会执行compute重新计算
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
System.out.println("v1:" + cache.get(1));
Thread.sleep(1000);
System.out.println("v2:" + cache.get(1));
Thread.sleep(5000);
}
@Test
public void testCache4() throws ExecutionException, InterruptedException {
//增加缓存值删除监听器
LoadingCache cache = CacheBuilder.newBuilder()
.removalListener(new RemovalListener() {
@Override
public void onRemoval(RemovalNotification removalNotification) {
System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
}
})
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
System.out.println("v1:" + cache.get(1));
Thread.sleep(1000);
System.out.println("v2:" + cache.get(1));
Thread.sleep(3000);
cache.invalidateAll();//invalidate亦会触发删除操作
Thread.sleep(3000);
}
@Test
public void testCache5() throws ExecutionException, InterruptedException {
//增加缓存值删除监听器
LoadingCache cache = CacheBuilder.newBuilder()
.removalListener(new RemovalListener() {
@Override
public void onRemoval(RemovalNotification removalNotification) {
System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
}
}).recordStats()
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
System.out.println("v1:" + cache.get(1));
Thread.sleep(1000);
System.out.println("v2:" + cache.get(1));
Thread.sleep(3000);
cache.invalidateAll();//invalidate亦会触发删除操作
Thread.sleep(3000);
System.out.println(cache.stats());
}
@Test
public void testCache6() throws ExecutionException, InterruptedException {
RemovalListener listener = RemovalListeners.asynchronous(new RemovalListener() {
@Override
public void onRemoval(RemovalNotification removalNotification) {
System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
}
}, Executors.newSingleThreadExecutor());
//增加缓存值删除异步监听器
LoadingCache cache = CacheBuilder.newBuilder()
.removalListener(listener).recordStats()
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
System.out.println("v1:" + cache.get(1));
Thread.sleep(1000);
System.out.println("v2:" + cache.get(1));
Thread.sleep(3000);
cache.invalidateAll();//invalidate亦会触发删除操作
Thread.sleep(3000);
System.out.println(cache.stats());
cache.cleanUp();
}
}
@Test
public void testCache7() throws ExecutionException, InterruptedException {
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
//增加缓存值删除异步监听器
LoadingCache cache = CacheBuilder.newBuilder()
.build(new CacheLoader() {
//cache for what
public String load(Integer key) {
return compute(key);
}
});
//每隔5分钟进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.MINUTES);
System.out.println("v1:" + cache.get(1));
Thread.sleep(1000);
System.out.println("v2:" + cache.get(1));
Thread.sleep(3000);
cache.invalidateAll();//invalidate亦会触发删除操作
Thread.sleep(3000);
cache.cleanUp();
}