您的位置:首页 > 其它

Guava LoadingCache使用记录

2017-11-22 09:30 435 查看
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<String> 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<Integer, String> cache = CacheBuilder.<Integer, String>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<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.build(new CacheLoader<Integer, String>() {
//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<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.build(new CacheLoader<Integer, String>() {
//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<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.removalListener(new RemovalListener<Integer, String>() {
@Override
public void onRemoval(RemovalNotification<Integer, String> removalNotification) {
System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
}
})
.build(new CacheLoader<Integer, String>() {
//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<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.removalListener(new RemovalListener<Integer, String>() {
@Override
public void onRemoval(RemovalNotification<Integer, String> 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<Integer, String>() {
//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<Integer, String> listener = RemovalListeners.asynchronous(new RemovalListener<Integer, String>() {
@Override
public void onRemoval(RemovalNotification<Integer, String> removalNotification) {
System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
}
}, Executors.newSingleThreadExecutor());
//增加缓存值删除异步监听器
LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.removalListener(listener).recordStats()
.build(new CacheLoader<Integer, String>() {
//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();
}
}



具体使用,建议加入定时更新(如果compute计算逻辑不固定)
@Test
public void testCache7() throws ExecutionException, InterruptedException {
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
//增加缓存值删除异步监听器
LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
.build(new CacheLoader<Integer, String>() {
//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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Guava Cache LoadingCache