Redis 增加互斥锁
互斥锁 缓存击穿后,多个线程会同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。 其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。static Lock reenLock = new ReentrantLock();public String findPubConfigByKey1(S
·
互斥锁
缓存击穿后,多个线程会同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。
其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。
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();
}
更多推荐
已为社区贡献1条内容
所有评论(0)