一.当采用reddis缓存的时候,如果同时,一万次访问,那么就会有10000次访问数据库所以就会对数据库造成巨大压力,这时候,就要用到线程

1.方法体上加锁(优点,防护住了并发锁,缺点降低了内存效率)

  /**
* 最简洁的高并发处理,但是,牺牲效率大
*
* @return
*/
public synchronized List<Student> selectAllStudent1() { // 字符串序列化器
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer); /**
* 在高并发条件下,此处有问题,缓存穿透问题
*/
//查询关键字
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents"); if (null == studentList) { //缓存为空,查询数据库
studentList = studentMapper.selectAllStudent(); //把数据库中查询出的数据,放入redis中
redisTemplate.opsForValue().set("allStudents", studentList);
} return studentList;
}

2.加双锁

 /**
* 双锁的提高效率版本
*
* @return
*/
@Override
public List<Student> selectAllStudent() { // 字符串序列化器
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer); /**
* 在高并发条件下,此处有问题,缓存穿透问题
*/
//查询关键字
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents"); if (null == studentList) {
//因为spring中的对象都是单例模式的,所以,直接对对象加锁
synchronized (this) {
// 从redis获取一下
studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
if (null == studentList) {
System.out.println("查询数据库*******************");
//缓存为空,查询数据库
studentList = studentMapper.selectAllStudent(); //把数据库中查询出的数据,放入redis中
redisTemplate.opsForValue().set("allStudents", studentList);
} else {
System.out.println("查询缓存*******************");
}
}
} else {
System.out.println("查询缓存*******************");
} return studentList;
}

二.Controller中加线程池进行效验

 /**
* Redis测试,完善好的高并发
*
* @return
*/
@GetMapping("/student/selectAllStudent")
public Object selectAllStudent() { //线程,该线程,调用底层查询所有学生方法
Runnable runnable = new Runnable() {
@Override
public void run() {
studentService.selectAllStudent();
}
}; //多线程测试穿透问题
ExecutorService executorService = Executors.newFixedThreadPool(25); for (int i = 0; i < 10000; i++) {
executorService.submit(runnable);
} return studentService.selectAllStudent();
}

三.源码地址

https://github.com/liushaoye/02-transaction/tree/reddis

IntelliJ IDEA 2017版 spring-boot2.0.4+mybatis+Redis处理高并发,穿透问题的更多相关文章

  1. Spring Boot2.0之 整合Redis集群

    项目目录结构: pom: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...

  2. Spring Boot2.0之 整合Redis事务

    Redis事物 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命 ...

  3. Spring Boot2.0之整合Redis

    需要的maven依赖 jar包,是对Jedis的封装 maven依赖: <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  4. IntelliJ IDEA 2017版 spring-boot 2.0.5 邮件发送简单实例 (三)

    一.搭建SpringBoot项目 详见此文:https://www.cnblogs.com/liuyangfirst/p/8298588.html 注意: 需要添加mail依赖的包,同时还添加了lom ...

  5. IntelliJ IDEA 2017版 spring-boot 2.0.3 部署war包项目和jar包项目

    1.建立项目 Java Controller package com.springboot.jsp.controller; import org.springframework.stereotype. ...

  6. IntelliJ IDEA 2017版 spring-boot 2.0.3 邮件发送搭建,概念梳理 (二)

    第二部分 邮件发送历史   一.第一封邮件   1.1969年10月,世界上的第一封电子邮件    1969年10月世界上的第一封电子邮件是由计算机科学家Leonard K.教授发给他的同事的一条简短 ...

  7. IntelliJ IDEA 2017版 spring-boot 2.0.3 邮件发送搭建,概念梳理 (一)

    邮件发送功能总结        第一部分 背景   一.使用场景 (1)注册验证    注册各大网站,通常需要输入邮件地址,在注册成功后,会发送一封邮箱验证的邮件,点击确认,证明这个邮箱是用户自己的 ...

  8. 【redis】在spring boot2.0中使用redis的StringRedisTemplate 自动注入@Autowired

    1.使用opv.increment 达到增量的效果[判断某个用户 是第几次做这种操作] @RequestMapping("createCode") @RestController ...

  9. Spring Boot2.0 设置拦截器

    所有功能完成 配置登录认证 配置拦截器 在spring boot2.0 之后 通过继承这个WebMvcConfigurer类 就可以完成拦截 新建包com.example.interceptor; 创 ...

随机推荐

  1. 利用sshtunnel实现跳板机的效果[嵌套ssh实现]

    with SSHTunnelForwarder ( ssh_address_or_host = (conf.server_ip,conf.server_port), ssh_username=conf ...

  2. sqlserver还原数据库失败,sql2008备份集中的数据库备份与现有的xxx数据库不同

    正常操作发现报标题错误,百度后解决思路如下(@参考文章)转到选项下面,勾选覆盖现有数据库即可

  3. 实现Hibernate框架的CRUD

    1.创建Web项目HS_test如图所示: 2.创建数据库DBHSTest,在数据库中创建表Teacher,并插入数据 3.在Myeclipse中调出DB Brower视图 右键->New: 连 ...

  4. 集成bug统计链接

    http://crab.baidu.com/http://bugly.qq.com/ http://bughd.com/ http://www.umeng.com/analyticshttp://tr ...

  5. div指令和mul指令

    div是除法指令,使用div做除法时需要注意: 1)除数:有8位和16位两种,在一个寄存器或者内存单元中 2)被除数:默认存放在AX或DX和AX中.如果除数为8位,被除数则为16位,默认在AX中存放: ...

  6. MySQL 中的数据类型介绍(转)

    据我统计,MySQL支持39种(按可使用的类型字段统计,即同义词也作多个)数据类型.下面的介绍可能在非常古老的mysql版本中不适用. 转载出处:http://blog.csdn.net/anxpp/ ...

  7. idea中lombok安装

    项目中经常使用bean,entity等类,绝大部分数据类类中都需要get.set.toString.equals和hashCode方法,虽然eclipse和idea开发环境下都有自动生成的快捷方式,但 ...

  8. /usr/local/ 和 /opt

    /usr/local:用户级的程序目录,可以理解为C:/Progrem Files/.用户自己编译的软件默认会安装到这个目录下. /opt:用户级的程序目录,可以理解为D:/Software,opt有 ...

  9. HTTP协议介绍(POST、GET、Content-Type)

    什么是HTTP?超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议.HTTP/1.1 协议规定的 HTTP 请求方法 ...

  10. C++中强制类型转换

    C++强制类型转换 C++中的强制类型转换虽然兼容C语言中的强制类型转换.但是并不建议在C++中使用C语言风格的强制类型转换.C++中的强制类型转换共有4个关键字分别是:static_cast,con ...