java使用guava cache实现本地缓存
原创 2021-02-04 15:39 阅读(4695)次
在高并发的场景中我们不希望所有请求都打到数据库中,以免压垮数据库,这时我们就可能会使用本地缓存来实现解决并发性能问题,当然我们也可以选择redis来实现,但redis有时并发也并没有那么快。于是本地缓存就是我们的唯一救命手段了。
Guava的cache是线程安全的,是本地缓存的不二之选,默认情况下缓存过期是依赖于访问判断时间过期和数量限制过期。
我们再也不用自己手写一个基于ConcurrentHashMap的本地缓存了
maven引入guava包
<!-- 本地缓存-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
两种缓存方式
guava的缓存提供两种方式:
1. 一种是在创建缓存时就提供加载缓存的方法load,在调用缓存时不用关注缓存数据从哪来,cache过期时会自动调用load去数据库或其他组件刷新缓存并返回给调用者。
2. 还有一种就是缓存失效后数据需要调用者手动更新缓存。
这两种方式大家可以根据场景去选择。
下面我提供一下我的代码示例,我的需求是要取缓存中的车牌,判断车辆是否存在缓存中,存在就不入库了。
自动加载缓存方式
代码示例:
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class VehicleNumCacheOnLoad {
private static Logger logger = LoggerFactory.getLogger(VehicleNumCacheOnLoad.class);
private final Integer existFlag = new Integer(1);
private LoadingCache<String,Integer> cache = CacheBuilder.newBuilder()
.recordStats()
.maximumSize(5000000)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build(
new CacheLoader<String, Integer>() {
@Override
public Integer load(String key) throws Exception {
//伪代码:
//查询数据库并返回existFlag
//return existFlag;
//数据库中查询不到,返回null
return null;
}
}
);
}
手动加载缓存方式
代码示例:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class VehicleNumCache {
private static Logger logger = LoggerFactory.getLogger(VehicleNumCache.class);
private final Integer existFlag = new Integer(1);
private Cache<String,Integer> cache = CacheBuilder.newBuilder()
.recordStats()
.maximumSize(5000000)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build();
/**
* 返回是否存在车辆,非null为存在
* @param vehicleNum
* @return
*/
public Integer get(String vehicleNum){
logger.info(cache.stats().toString());
return cache.getIfPresent(vehicleNum);
}
/**
* 返回是否存在车辆,非null为存在
* @param vehicleNum
* @return
*/
public void put(String vehicleNum){
cache.put(vehicleNum,existFlag);
}
}
如何调用
代码示例:
Integer flag = vehicleNumCache.get(vehicleNum);
//缓存不存在
if(flag == null){
filterVehicleList.add(v);
}
调用前记得注入缓存类vehicleNumCache