勿忘初心 厚德载物

《分布式服务架构》-分布式微服务架构设计原理

Posted on By JettyLee

双重检测锁解决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() {
	       //具体实现
	      }
	    });
	}