互斥锁
缓存击穿后,多个线程会同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。
其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。
static Lock reenLock = new ReentrantLock(); public String findPubConfigByKey1(String key) throws InterruptedException { PubConfig result = new PubConfig(); // 从缓存读取数据 result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ; if (result== null ) { if (reenLock.tryLock()) { try { System.out.println("拿到锁了,从DB获取数据库后写入缓存"); // 从数据库查询数据 result = pubConfigRepository.queryPubConfigInfoByKey(key); // 将查询到的数据写入缓存 Gson g = new Gson(); String value = g.toJson(result); redisService.setNx(PubConfigKeyConstants.TABLE_NAME + "_"+key, value); } finally { reenLock.unlock();// 释放锁 } } else { // 先查一下缓存 result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ; if (result== null) { System.out.println("我没拿到锁,缓存也没数据,先小憩一下"); Thread.sleep(100);// 小憩一会儿 return findPubConfigByKey1(key);// 重试 } } } return result.getValue(); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)