一.当采用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. 【校招面试 之 C/C++】第14题 C++ 内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区(堆栈的区别)

    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...

  2. 第五章 Inheritance继承

    [继承] Java不支持多重继承 - 每个子类只有一个超类. 不是将成员变量声明为静态,更好的做法是将University实例化为对象,然后使用该对象访问其成员,如下所示: [抽象类] 可以包含或者不 ...

  3. cherry-pick 命令

    拣选会提取某次提交的补丁,之后尝试将其重新应用到当前分支上. 这种方式在你只想引入特性分支中的某个提交时很有用. 假设你的项目提交历史如下: 如果你希望将提交 e43a6 拉取到 master 分支, ...

  4. php5.6 版本出现 Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version 的错误

    解决方法是修改php.ini配置: ;always_populate_raw_post_data = -1 把前面的分号去掉 always_populate_raw_post_data = -1 然后 ...

  5. spyder在编辑过程中被自己弄乱了,想要恢复成安装时默认的格式或者重置页面格式的解决办法

    打开spyder,tools-->Reset Spyder to factory defaults,按照如上操作即可恢复成安装时的默认格式.

  6. mysql修改表引擎Engine

    修改my.ini,在[mysqld]下加上default-storage-engine=INNODB 其中红色字体部分是要指定的引擎名称.用sql语句修改已经建成表的引擎:alter table ta ...

  7. Linux 编译时内存不足

    1.编译内核出现问题:No space left on device AS      .tmp_kallsyms1.o .tmp_kallsyms1.S:2: fatal error: when wr ...

  8. web 框架本质 及python三大框架对比

    . 导入Bootstrap.css (开发版3.3.7) . 还要Bootstrap.js,并且还要引入jQuery(). . 栅格系统 . container,row必须包含在container中 ...

  9. C# 一个数组未赋值引发的错误

    在电脑前又是一天,后来脑子也糊里糊涂,可能是基础还不牢固,设置断点,找了找问题才发现数组定义出了问题, 我是这样定义数组的,string[] auths ; string auths=new stri ...

  10. 放大Button热区的方法哟

    //添加图片不能用backgroundimage [btn setImage:image5 forState:]; //然后 btn.imageEdgeInsets = UIEdgeInsetsMak ...