本地锁锁住当前进程
//从数据库查询并封装分类数据
public Map<String, List<Catelog2Vo>> getCatalogJsonFromDb() {
//只要是同一把锁,就能锁住需要这个锁的所有线程,使用this,this代表的就是当前对象
//1.synchronized(this):SpringBoot所有的组件在容器中都是单例的
/**
* 100万个请求同时进来,进来以后就先锁住,接下来这100万个请求就来竞争锁,假设有一个竞争上来了,那他就去执行数据库查询,查询完以后返回,释放锁
* 别的请求再一进来,再去查数据库就是不合理的,相当于我们虽然锁住了,相当于再去排队查数据库。
* 所以拿到锁以后,进来要做的第一件事,就是再看一下缓存里面有没有,如果有了说明是上一个人执行完放好的,如果没有你才需要再去查
*/
//TODO 本地锁:synchronized,JUC(Lock),在分布式情况下,想要锁住所有,必须使用分布式锁
synchronized (this) {
//得到锁以后,我们应该再去缓存中确定一次,如果没有才需要继续查询
String catalogJSON = redisTemplate.opsForValue().get("catalogJSON");
if (!StringUtils.isEmpty(catalogJSON)) {
//缓存不为null直接返回
Map<String, List<Catelog2Vo>> result = JSON.parseObject(catalogJSON, new TypeReference<Map<String, List<Catelog2Vo>>>(){});
return result;
}
System.out.println("查询了数据库....");
//将数据库的多次查询变为一次
Map<String, List<Catelog2Vo>> parentCid = selectFromDB();
return parentCid;
}
}
如果是在单体应用的情况下,也就是我们这个项目只会部署在一个Tomat里面,一台服务器,这样加锁没问题。