双重检测锁解决Redis缓存穿透问题
redis缓存常规写法代码
@Autowired
RedisTemplate<Object, Object> redisTemplate;
public List<User> test() {
List<User> list =(List<User>) redisTemplate.opsForValue().get("userList");
if(null==list) {
System.out.println("从数据库中读取");
list=userDao.selectSample();
redisTemplate.opsForValue().set("userList",list);
}
return list;
}
双重检测锁-改进
注:这个改进针对当前对象是单例对象
@Autowired
RedisTemplate<Object, Object> redisTemplate;
public List<User> test() {
List<User> list =(List<User>) redisTemplate.opsForValue().get("userList");
//判断缓存有没有
if(null==list) {
//当前对象加锁
synchronized (this) {
//缓存重新取一次
list =(List<User>) redisTemplate.opsForValue().get("userList");
//若还是没有
if(null==list) {
System.out.println("从数据库中读取");
list=userDao.selectSample();
redisTemplate.opsForValue().set("userList",list);
}else {
System.out.println("锁等待,从缓存中读取");
}
}
}else {
System.out.println("从缓存中读取");
}
return list;
}
测试方法
ExecutorService executorService= Executors.newFixedThreadPool(20);
for(int i=1 ; i<=1000;i++){
executorService.submit(new Runnable() {
@Override
public void run() {
//具体实现
}
});
}