当前位置: 首页 > news >正文

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九

前言


如题,该篇实践教程就是简单的抛砖引玉,通过实现一个简单的排队场景,带着大家熟悉下 redis里list数据结构的相关操作。

 

正文

 

在开始编码前,我们先简单了解下该篇实践教程实现 排队场景,

包括哪些功能:

1. 正常排队

2.队伍总人数

3.队伍信息

4.某人离开队伍

5.正常排队完离开队伍

6.某人在队伍的所在位置,前面人数,后面人数

7.插队 (道德不允许,咱们只是做个例子)

 

开始编码:

 

ps :怎么整合redis这篇文章就不介绍了,如果还不会的可以看我的这个系列的教程。

 

为了方便咱们的演示,直接通过写接口调接口的方式。

创建一个MyTestController.java,注入一下RedisTemplate:

/**
 * @Author : JCccc
 * @CreateTime : 2020/3/27
 * @Description :
 **/

@Controller
@RequestMapping("/test")
public class MyTestController {

    @Autowired
    private RedisTemplate redisTemplate;


}

1. 正常排队

    /**
     * 加入队伍
     * @param userId
     */
    @ResponseBody
    @GetMapping("/addQueue")
    public void addQueue(@RequestParam("userId") String userId) {
      //  redisTemplate.opsForList().leftPush("myQueue",userId);
        redisTemplate.opsForList().rightPush("yourQueue",userId);
    }

 

可以看到这个接口里面,我的代码有一行注释的,其实两行低吗都是往队伍里面去添加数据达到 排队加入队伍的功能。

而通过数据顺序来说,我选择使用rightPush,这样更能容易理解排队的原则,先进先出。

 

那么我们开始调用接口 /addQueue ,看看效果:

可以看到redis里面的数据,01 妥妥地加入到了队伍: 

 

 

重复上面的操作,模拟出一个小队列数据,将02,03,04,05 也按顺序排队加入到队伍里,结果如:

2.队伍总人数

    /**
     * 队伍总人数
     */
    @ResponseBody
    @GetMapping("/queueCount")
    public String queueCount() {
        Long listSize = redisTemplate.opsForList().size("yourQueue");
       return "队伍总人数:"+listSize;
    }

调用接口,查看队伍总人数:

 3.队伍信息

    /**
     * 队伍详情
     */
    @ResponseBody
    @GetMapping("/queueData")
    public String queueData() {
        List listData = redisTemplate.opsForList().range("yourQueue", 0, -1);
        return listData.toString();
    }

调用接口,查看队伍详情:

 4.某人离开队伍

    /**
     * 离开队伍
     * @param userId
     */
    @ResponseBody
    @GetMapping("/leaveQueue")
    public void leaveQueue(@RequestParam("userId") String userId) {
        Long removeNum = redisTemplate.opsForList().remove("yourQueue", 0, userId);
        System.out.println(removeNum);
    }

这个接口里面使用的方法,第二个参数,需要注意:

对于list数据其实是允许重复的,但是我们模拟的队列数据,给用户分配的userId保持唯一。

但是原有的remove方法使兼容了重复数据移除的场景,
当传入 0: 移除整个队列里的 目标值 ,也就是录入传入userId是01,

那么有一个也移除,有N个也移除,反正保证干干净净。

当传入小于0的数,如-1或者传入大于0的数,如1: 就是不同顺序去检查这个队伍,直到碰到第一个目标值,进行删除。 

 

调用接口,模拟 03 这个用户离开队伍:

结果:

5.正常排队完离开队伍

    /**
     * 默认离队,先进先出
     */
    @ResponseBody
    @GetMapping("/defaultLeaveQueue")
    public void defaultLeaveQueue() {

        redisTemplate.opsForList().leftPop("yourQueue");
    }

当前队伍里面01排在最前面,所以当调用接口时,默认排完队离开的就是01,先进先出:

结果:

6.某人在队伍的所在位置, 前面人数,后面人数

    /**
     * 查看我自己的队列位置
     * @param userId
     */
    @ResponseBody
    @GetMapping("/getMyPosition")
    public void getMyPosition(@RequestParam("userId") String userId){
        List listData = redisTemplate.opsForList().range("yourQueue", 0, -1);
        int myPositionBeforeNum = listData.indexOf(userId);
        int myPositionNum = listData.indexOf(userId)+1;
        int size=listData.size();
        System.out.println("所在位置前面人数:"+myPositionBeforeNum);
        System.out.println("所在位置:"+myPositionNum);
        System.out.println("所在位置后面人数:"+(size-myPositionNum));
    }

调用接口,查看04所在队伍的位置,以及他前面还有多少人,后面还有多少人:

结果:

 

7.插队  

ps:有时候业务需要插队场景还是有需要的

    /**
     * 野蛮插队
     * @param userId
     * @param toUserId
     */
    @ResponseBody
    @GetMapping("/savageAction")
    public void savageAction(@RequestParam("userId") String userId ,@RequestParam("toUserId") String toUserId,@RequestParam("type") String type){

            //userId 插队人
            //toUserId 被插队人
            //before 插前面
            //after 插后面
           if ("before".equals(type)){
               redisTemplate.opsForList().leftPush("yourQueue",toUserId,userId);
             }
           if ("after".equals(type)){
               redisTemplate.opsForList().rightPush("yourQueue",toUserId,userId);
           }
    }

插队有分插前面和后面,调用接口,模拟一个新用户 2020 插队,插入到了04这个用户前面:

结果:
 

 再调用接口,模拟一个新用户 3003 插队,插入到了2020这个用户后面:

结果:
 

 

 

该篇就到此。 

相关文章:

  • Springboot 自定义注解+AOP简单实例介绍
  • Java 将Map的toString格式字符串转为 Map
  • Java 细品 重写equals方法 和 hashcode 方法
  • Java 对象的克隆Clone和必须了解的浅拷贝与深拷贝
  • Java i++ 与 ++i
  • Java try 与 finally 对于返回值的影响
  • 手撕一道算法题 在你面前有一个n阶的楼梯,你一步只能上1阶或2阶。请问,当N=11时,你可以采用多少种不同的方式爬完这个楼梯();当N=9时呢?
  • Springboot 整合tk-mybatis , 妈妈,我再也不想敲CRUD的代码了!
  • 【硬着头皮】你还在用size来判断集合是否为空?
  • 【硬着头皮】PageHelper 必须用来分页?
  • Java 使用LRUmap设计一个简单的缓存场景
  • MYSQL 查找单个字段或者多个字段重复数据,清除重复数据
  • 先了解清楚 脏读、不可重复读、幻读,再谈事务隔离机制
  • ActiveMQ 启动报错 Address already in use: JVM_Bind 5672
  • ActiveMQ 无法注入 jmsMessagingTemplate
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Apache Pulsar 2.1 重磅发布
  • canvas 五子棋游戏
  • const let
  • java 多线程基础, 我觉得还是有必要看看的
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • Java 最常见的 200+ 面试题:面试必备
  • JavaWeb(学习笔记二)
  • python3 使用 asyncio 代替线程
  • 关于Flux,Vuex,Redux的思考
  • 如何胜任知名企业的商业数据分析师?
  • 试着探索高并发下的系统架构面貌
  • 树莓派用上kodexplorer也能玩成私有网盘
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (0)Nginx 功能特性
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (十) 初识 Docker file
  • (五)IO流之ByteArrayInput/OutputStream
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • .Net - 类的介绍
  • .NET Reactor简单使用教程
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • @angular/cli项目构建--http(2)
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • @拔赤:Web前端开发十日谈
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [14]内置对象
  • [20170705]diff比较执行结果的内容.txt
  • [AIGC] Spring Interceptor 拦截器详解
  • [Angular 基础] - 指令(directives)
  • [bzoj 3534][Sdoi2014] 重建
  • [C++] sqlite3_get_table 的使用
  • [git] windows系统安装git教程和配置
  • [IE技巧] IE8中HTTP连接数目的变化
  • [javaSE] 数据结构(二叉查找树-插入节点)
  • [LeetCode] 196. 删除重复的电子邮箱
  • [LeetCode] Sort List