zoukankan      html  css  js  c++  java
  • IntelliJ IDEA 2017版 spring-boot2.0.4+mybatis+Redis处理高并发,穿透问题

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

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

     1  /**
     2      * 最简洁的高并发处理,但是,牺牲效率大
     3      *
     4      * @return
     5      */
     6     public synchronized List<Student> selectAllStudent1() {
     7 
     8         // 字符串序列化器
     9         RedisSerializer redisSerializer = new StringRedisSerializer();
    10         redisTemplate.setKeySerializer(redisSerializer);
    11 
    12         /**
    13          * 在高并发条件下,此处有问题,缓存穿透问题
    14          */
    15         //查询关键字
    16         List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
    17 
    18         if (null == studentList) {
    19 
    20             //缓存为空,查询数据库
    21             studentList = studentMapper.selectAllStudent();
    22 
    23             //把数据库中查询出的数据,放入redis中
    24             redisTemplate.opsForValue().set("allStudents", studentList);
    25         }
    26 
    27         return studentList;
    28     }
    View Code

        2.加双锁

     1 /**
     2      * 双锁的提高效率版本
     3      *
     4      * @return
     5      */
     6     @Override
     7     public List<Student> selectAllStudent() {
     8 
     9         // 字符串序列化器
    10         RedisSerializer redisSerializer = new StringRedisSerializer();
    11         redisTemplate.setKeySerializer(redisSerializer);
    12 
    13         /**
    14          * 在高并发条件下,此处有问题,缓存穿透问题
    15          */
    16         //查询关键字
    17         List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
    18 
    19         if (null == studentList) {
    20             //因为spring中的对象都是单例模式的,所以,直接对对象加锁
    21             synchronized (this) {
    22                 // 从redis获取一下
    23                 studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
    24                 if (null == studentList) {
    25                     System.out.println("查询数据库*******************");
    26                     //缓存为空,查询数据库
    27                     studentList = studentMapper.selectAllStudent();
    28 
    29                     //把数据库中查询出的数据,放入redis中
    30                     redisTemplate.opsForValue().set("allStudents", studentList);
    31                 } else {
    32                     System.out.println("查询缓存*******************");
    33                 }
    34             }
    35         } else {
    36             System.out.println("查询缓存*******************");
    37         }
    38 
    39         return studentList;
    40     }
    View Code

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

     1 /**
     2      * Redis测试,完善好的高并发
     3      *
     4      * @return
     5      */
     6     @GetMapping("/student/selectAllStudent")
     7     public Object selectAllStudent() {
     8 
     9         //线程,该线程,调用底层查询所有学生方法
    10         Runnable runnable = new Runnable() {
    11             @Override
    12             public void run() {
    13                 studentService.selectAllStudent();
    14             }
    15         };
    16 
    17 
    18         //多线程测试穿透问题
    19         ExecutorService executorService = Executors.newFixedThreadPool(25);
    20 
    21         for (int i = 0; i < 10000; i++) {
    22             executorService.submit(runnable);
    23         }
    24 
    25         return studentService.selectAllStudent();
    26     }
    View Code

    三.源码地址

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

  • 相关阅读:
    谈我们为什么学不好编程2——你是否已进入“等死模式”?
    JSP使用SmartUpload实现文件上传
    内核模块编程练习
    Vue++:Vue中 关于$emit的用法
    Vue++:Vue 脚手架在vue.config.js文件中配置scss全局变量
    Vue++:Vuecli3.0 脚手架搭建项目
    Java++:七个开源的 Spring Boot 前后端分离项目,一定要收藏!
    MySQL++:SQL 优化的15个小技巧
    RabbitMQ++:RabbitMQ 的队列(Queue)的参数及其含义
    Vue++:Vue 二级路由不显示页面问题
  • 原文地址:https://www.cnblogs.com/liuyangfirst/p/9279925.html
Copyright © 2011-2022 走看看