SpringBoot整合Redis使用同步锁
日期: 2019-03-01 分类: 个人收藏 313次阅读
如果项目已经用到缓存技术了,一般访问量都比较多了吧,刚才我们上面的请求只是做了缓存处理,考虑一个问题:当在高并发条件下,我们假设至少有1W人同时访问获取学生的信息。
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("students");
那么studentList为空,1W人进入访问数据库。
if (studentList == null) {
/*从mysql数据库中查询*/
studentList = studentService.getStudents();
/*保存到redis数据库*/
redisTemplate.opsForValue().set("students", studentList);
}
在处理高并发,我们可以使用synchronized同步锁。
同步机制:synchronized是Java同步机制的一种实现,即互斥锁机制,它所获得的锁叫做互斥锁。
互斥锁:指的是每个对象的锁一次只能分配给一个线程,同一时间只能由一个线程占用。
作用:synchronized用于保证同一时刻只能由一个线程进入到临界区,同时保证共享变量的可见性、原子性和有序性。
使用: 当一个线程试图访问同步代码方法(块)时,它首先必须得到锁,退出或抛出异常时必须释放锁。
@GetMapping(value = "/getStudents")
@ResponseBody
public /*synchronized*/ Object getStudents(){
/*redis的序列化器*/
RedisSerializer redisSerializer = new StringRedisSerializer();
/*设置redisTemplate序列化器*/
redisTemplate.setKeySerializer(redisSerializer);
//高并发条件下,此处有点问题,缓存穿透
/*先从redis 缓存中查询*/
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("students");
//双重检测锁
if (studentList == null) {
synchronized (this) {
//从redis中获取一下
studentList = (List<Student>) redisTemplate.opsForValue().get("students");
if (studentList == null) {
/*从mysql数据库中查询*/
studentList = studentService.getStudents();
/*保存到redis数据库*/
redisTemplate.opsForValue().set("students", studentList);
}
}
}
return studentList;
}
可以把锁加在方法上面,但是对性能不是很好,所以我们把锁加在代码块上,双重检测锁可以提升性能。
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:Java
精华推荐