synchronized实现双重检查锁避免Redis缓存击穿

缓存击穿:

对于某一个缓存,在高并发情况下若其访问量特别巨大,当该缓存的有效时限
到达时,可能会出现大量的访问都要重建该缓存,即这些访问请求发现缓存中
没有该数据,则立即到 DBMS 中进行查询,那么这就有可能会引发对 DBMS
高并发查询,从而接导致 DBMS 的崩溃。这种情况称为缓存击穿,而该缓存数
据称为热点数据。
步骤如下:
  • 先查 reids 中是否有数据
  • 如果 redis 中没有数据,使用 synchronized 进行加锁
  • 再次查询 reids 中是否有数据
  • 如果第3步查询还是没有数据,此时再查数据库
  • 查询到数据库中的数据后,将数据写入到redis中
public Double findTurnover() {
        // 获取Redis操作对象
        BoundValueOperations<Object, Object> ops = template.boundValueOps("turnover");
        // 从缓存获取turnover
        Object turnover = ops.get();
        //取不到加锁
        if (turnover == null) {
            synchronized (this) {
                turnover = ops.get();
                // 若缓存中没有,则从DB中查询
                if (turnover == null) {
                    Date date = new Date();
                    //根据当前时间获取交易额
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    turnover = dao.selectTurnover(sdf.format(date));
                    // 将从DB中查询的结果写入到缓存,并指定过期时间
                    ops.set(turnover, 10, TimeUnit.SECONDS);
                }
            }
        }
        return (Double) turnover;
    }

使用双重检查锁的方法,可以避免高并发情况下,所有请求直接到数据库上

猜你喜欢

转载自blog.csdn.net/qq_52183856/article/details/131792774