redis系列:通过队列案例学习list命令

前言

这一篇文章将讲述Redis中的list类型命令,同样也是通过demo来讲述,其他部分这里就不在赘述了。

项目Github地址:https://github.com/rainbowda/learnWay/tree/master/learnRedis/case-list

案例

demo功能是队列,整个demo的大致页面如下。左边是存储到Redis中的数据,右边是从Redis中弹出的数据。

准备工作

首先定义一个存储list的key

private static final String LIST_KEY = "list:1";

队列的key就用list:1

redis操作对象

private RedisTemplate redisTemplate;
//string 命令操作对象
private ValueOperations valueOperations;
//list 命令操作对象
private ListOperations listOperations;

list在Redis中的结构可以看下图(图片来源于Redis in Action)。

插入数据

头部插入

命令介绍

命令用例描述
LPUSHLPUSH key value [value ...]将所有指定的值插入到存于 key 的列表的头部。 如果 key 不存在,那么在进行 push 操作前会创建一个空列表。
LPUSHXLPUSHX key value只有当 key 已经存在并且存着一个 list 的时候,在这个 key 下面的 list 的头部插入 value。

接下来看看demo中头部插入的功能,点击下图中头部插入按钮,然后在弹出框中填入数字0,点击提交后整个头部插入流程结束。可以看到左边的队列数据出现了一条{"data":"0"} 数据,在数据{"data":"1"} 上面。

来看看后台的方法

@RequestMapping(value = "/leftPop",method = RequestMethod.GET)
public Object leftPop(){return listOperations.leftPop(LIST_KEY);
}

如果需要在Redis中操作,可以敲下面的命令

lpush list:1 "{\"data\":\"0\"}" 

尾部插入

命令介绍

命令用例描述
RPUSHRPUSH key value [value ...]向存于 key 的列表的尾部插入所有指定的值。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作。
RPUSHXRPUSHX key value将值 value 插入到列表 key 的表尾, 当且仅当 key 存在并且是一个列表。

接下来看看demo中尾部插入的功能,点击下图中尾部插入按钮,然后在弹出框中填入数字11,点击提交后整个新增流程结束。可以看到左边的队列数据出现了一条{"data":"11"} 数据,在数据{"data":"10"}下面。

来看看后台的方法

@RequestMapping(value = "/rightPop",method = RequestMethod.GET)
public Object rightPop(){return listOperations.rightPop(LIST_KEY);
}

如果需要在Redis中操作,可以敲下面的命令

rpush list:1 "{\"data\":\"11\"}" 

列表查询

命令介绍

同样先看看相关的获取值命令

命令用例描述
LRANGELRANGE key start stop返回存储在 key 的列表里指定范围内的元素。
LINDEXLINDEX key index返回列表里的元素的索引 index 存储在 key 里面。
LLENLLEN key返回存储在 key 里的list的长度。

后台查询方法,将新增的内容查询出来

@RequestMapping(value = "/getList",method = RequestMethod.GET)
public List getList(){List list = listOperations.range(LIST_KEY, 0, -1);//可以用size获取成员长度//listOperations.size(LIST_KEY);return list;
}

数据弹出

头部弹出

命令用例描述
LPOPLPOP key移除并且返回 key 对应的 list 的第一个元素。
BLPOPBLPOP key [key ...] timeout它是命令 LPOP 的阻塞版本,这是因为当给定列表内没有任何元素可供弹出的时候, 连接将被 BLPOP 命令阻塞。

接下来看看头部弹出的功能,点击下图中头部弹出按钮,可以看到左边的队列顶部数据减少了,在右边弹出的数据出现了左边队列数据消失的数据。

来看看后台的方法

@RequestMapping(value = "/leftPop",method = RequestMethod.GET)
public Object leftPop(){return listOperations.leftPop(LIST_KEY);
}

如果需要在Redis中操作,可以敲下面的命令

lpop list:1 

尾部弹出

命令用例描述
RPOPRPOP key移除并返回存于 key 的 list 的最后一个元素。
BRPOPBRPOP key [key ...] timeout它是 RPOP 的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候阻塞连接。

接下来看看尾部弹出的功能,点击下图中尾部弹出按钮,可以看到左边的队列尾部数据减少了,在右边弹出的数据出现了左边队列数据消失的数据。

来看看后台的方法

@RequestMapping(value = "/rightPop",method = RequestMethod.GET)
public Object rightPop(){return listOperations.rightPop(LIST_KEY);
}

如果需要在Redis中操作,可以敲下面的命令

rpop list:1 

其他命令

命令用例描述
LINSERTLINSERT key BEFORE\AFTER pivot value把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
LREMLREM key count value从存于 key 的列表里移除前 count 次出现的值为 value 的元素。
LSETLSET key index value设置 index 位置的list元素的值为 value。
LTRIMLTRIM key start stop修剪(trim)一个已存在的 list,这样 list 就会只包含指定范围的指定元素。
RPOPLPUSHRPOPLPUSH source destination原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素), 并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)。
BRPOPLPUSHBRPOPLPUSH source destination timeoutBRPOPLPUSH 是 RPOPLPUSH 的阻塞版本。

RPOPLPUSH和BRPOPLPUSH

这两个命令作用其实是相同的,只不过BRPOPLPUSH是阻塞的,当没有数据时,会一直阻塞,直到有数据。

在Redis官方文档中,用RPOPLPUSH命令举了两个例子,一个是Reliable queue(安全的队列 ),另一个是Circular list(循环列表)。

Reliable queue(安全的队列 )

Redis通常都被用做一个处理各种后台工作或消息任务的消息服务器。 一个简单的队列模式就是:生产者把消息放入一个列表中,等待消息的消费者用 RPOP 命令(用轮询方式), 或者用 BRPOP 命令(如果客户端使用阻塞操作会更好)来得到这个消息。

然而,因为消息有可能会丢失,所以这种队列并是不安全的。例如,当接收到消息后,出现了网络问题或者消费者端崩溃了, 那么这个消息就丢失了。

RPOPLPUSH (或者其阻塞版本的 BRPOPLPUSH) 提供了一种方法来避免这个问题:消费者端取到消息的同时把该消息放入一个正在处理中的列表。 当消息被处理了之后,该命令会使用 LREM 命令来移除正在处理中列表中的对应消息。

另外,可以添加一个客户端来监控这个正在处理中列表,如果有某些消息已经在这个列表中存在很长时间了(即超过一定的处理时限), 那么这个客户端会把这些超时消息重新加入到队列中。

翻译来自 http://www.redis.cn/commands/rpoplpush.html

Circular list(循环列表)

RPOPLPUSH 命令的 source 和 destination 是相同的话, 那么客户端在访问一个拥有n个元素的列表时,可以在 O(N) 时间里一个接一个获取列表元素, 而不用像 LRANGE那样需要把整个列表从服务器端传送到客户端。

上面这种模式即使在以下两种情况下照样能很好地工作: 有多个客户端同时对同一个列表进行旋转(rotating):它们会取得不同的元素,直到列表里所有元素都被访问过,又从头开始这个操作。 有其他客户端在往列表末端加入新的元素。

这个模式让我们可以很容易地实现这样一个系统:有 N 个客户端,需要连续不断地对一批元素进行处理,而且处理的过程必须尽可能地快。 一个典型的例子就是服务器上的监控程序:它们需要在尽可能短的时间内,并行地检查一批网站,确保它们的可访问性。

值得注意的是,使用这个模式的客户端是易于扩展(scalable)且安全的(reliable),因为即使客户端把接收到的消息丢失了, 这个消息依然存在于队列中,等下次迭代到它的时候,由其他客户端进行处理。

翻译来自 http://www.redis.cn/commands/rpoplpush.html

案例-约瑟夫问题

约瑟夫问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环

人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并沿指定方向围绕圆圈进行。 在跳过指定数量的人之后,执行下一个人。 对剩下的人重复该过程,从下一个人开始,朝同一方向跳过相同数量的人,直到只剩下一个人,并被释放。

问题即,给定人数、起点、方向和要跳过的数字,选择初始圆圈中的位置以避免被处决。

来自维基百科 https://zh.wikipedia.org/wiki/%E7%BA%A6%E7%91%9F%E5%A4%AB%E6%96%AF%E9%97%AE%E9%A2%98

思路

定义一个list key为josephus,利用

RPOPLPUSH  josephus josephus

命令来构造循环链表,每当数到3时,使用rpop

rpop josephus

命令弹出

代码实现

public class JosephusProblem extends RedisBaseConnection {@Testpublic void test() {//构造数据for (int i = 1; i <= 41; i++) {listOperations.leftPush("josephus", String.valueOf(i));}int index = 1;while (listOperations.size("josephus") > 0) {//当数到3时,弹出if (index == 3) {System.out.println(listOperations.range("josephus", 0, -1));System.out.println("当前被杀的人是:" + listOperations.rightPop("josephus"));index = 0;} else {listOperations.rightPopAndLeftPush("josephus", "josephus");}index++;}}
}

整个代码步骤如下

  1. 先是模拟有41个人(向redis中key为josephus的list添加41个数据)
  2. 定义索引index
  3. 循环判断key为josephus的数据长度是否大于0
  4. 当索引index为3时,调用Redis的rpop命令弹出对应的数据。索引index不为3时,调用RPOPLPUSH命令,将对应的数据放到队列头部
  5. 索引index加1

运行结果有点长,这里只截图最后一部分的结果,如下

约瑟夫问题代码请点击JosephusProblem.java


建议学习的人最好每个命令都去敲下,加深印象。下面诗句送给你们。

纸上得来终觉浅,绝知此事要躬行。————出自《冬夜读书示子聿》


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/520958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019年程序员薪酬报告:平均年薪超70万!40岁后,这类人不“保值”了

Hired 近日发布了《2019 年度薪酬状况报告》&#xff0c;重点结论如下&#xff1a;仅有 23% 的硕士 / 博士表示&#xff0c;高学历带来了高薪&#xff0c;大部分人表示学历不是全部76% 的技术工作者认为&#xff0c;参加编程培训机构对求职有帮助在美国&#xff0c;技术工作者在…

业务代码解构利器--SWAK

简介 业务的不断发展、商品类型的不断增多、不断添加的业务需求使得闲鱼的代码出现“bad smell”——平台代码和业务代码耦合严重难以分离&#xff1b;业务和业务之间代码交织缺少拆解。这也是行业中的通病。为解决此类问题&#xff0c;闲鱼自研了一套技术框架——SWAK。本文带…

(Docker实战) 第4篇:Centos7 拉取和部署Redis

文章目录搭建redis搭建redis docker run --name redis -di --publish 6379:6379 redis:4.0远程验证测试&#xff1a; 想学习更多微服务、分布式、中间件、数据库、项目快速构建等系列技术 请访问http://gblfy.com 让我们一起进步&#xff01;&#xff01;&#xff01;

阿里巴巴上线静态开源站点搭建工具 Docsite

近日&#xff0c;阿里巴巴在Github上线了静态开源站点搭建工具Docsite&#xff0c;这是一款集官网、文档、博客和社区为一体的静态开源站点的解决方案&#xff0c;具有简单易上手、上手不撒手的特质&#xff0c;同时支持react和静态渲染、PC端和移动端、支持中英文国际化、SEO、…

重磅 | 边缘计算核心技术辨析

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 中国电信广研院责编 | 阿秃边缘计算&#xff08;Edge Computing&#xff09;是云计算向边缘的延伸&#xff0c;本文对边缘计算、雾计算、MEC、Cloudlet、分布式云等边缘计算领域相关概念和技术的定义、架构、场景等进行了比…

php请求接口两次,php curl post请求执行一次curl_exce 请求的接口确执行两次

1、php curl post请求接口&#xff0c;打印日志执行了一次curl_exce&#xff0c;但是请求的接口却重复执行两次.2、代码&#xff1a;$ch curl_init();if(false $ch){writeRedisLog(create_curl, $activity_id, $mobile, $user_id, , 0, curl failed to initialize);}curl_set…

(Docker实战) 第5篇:Centos7 拉取和部署搭建 NEXUS私服

文章目录搭建nexus私服1. 安装nexus3&#xff08;admin/admin123&#xff09;2 .配置nexus32.1 新建一个maven2(proxy)仓库2.2. 新建一个maven2(hosted)仓库2.3. 配置public仓库搭建nexus私服 1. 安装nexus3&#xff08;admin/admin123&#xff09; #创建文件夹,安装过程如果…

Nacos发布 v0.2 版本,无缝支持 Spring Cloud 微服务生态及高可用集群模式

近日&#xff0c;阿里巴巴新开源项目Nacos 发布了 v0.2 版本&#xff0c;该版本开始支持完整的Spring生态技术栈&#xff0c;这包括 Spring Framework、Spring Boot和Spring Cloud。 为了让更多的Spring用户可以在生产上基于 Nacos 做微服务平台的服务发现、配置管理、服务管控…

是时候展现真正的技术了!4道程序员智力题你能对几道| IT巨能唠

程序员对很多人来说那就是个神秘组织&#xff0c;高薪、加班多都是他们的代名词。但是&#xff0c;大家好像还忘了一点&#xff0c;那就是他们也绝对聪明&#xff01;黑客、代码天才、编程老手……层出不穷&#xff0c;晦涩的计算机难题也是分分钟搞定&#xff0c;想想就令人神…

阿里关涛谈大规模计算—从数字化阿里到数字化城市的进化

在刚刚结束的2018杭州云栖大会上&#xff0c;阿里巴巴通用计算平台负责人&#xff0c;阿里巴巴计算平台资深技术专家关涛从计算力&#xff0c;联合计算&#xff0c;智能化&#xff0c;企业级服务能力四个方面详细介绍阿里巴巴统一的超大规模数据计算平台MaxCompute的探索与实践…

15年大厂经历!大佬总结:0基础如何学习Python?

在学习之前&#xff0c;你一定要知道你的学习目标是什么。现在市面上有太多人鼓吹“Python太火了”、“Python第一”。但是&#xff0c;注意&#xff0c;“火”、“第一”一定不能成为你学习的理由&#xff0c;千万别火急火燎的随大流。正确做法是&#xff0c;看看市面上的真正…

STL体系结构概述

文章目录 STL是什么&#xff1f;STL的六大组件STL的实现版本额外补充一、容器范围区间二、容器结构与分类序列式容器关联容器有序关联容器不定序关联容器 参考 本文将是STL系列的第一篇文章&#xff0c;主要参考《STL源码剖析》&#xff0c;辅以网络博文&#xff0c;不定时更新…

迁移学习让深度学习更容易

深度学习在一些传统方法难以处理的领域有了很大的进展。这种成功是由于改变了传统机器学习的几个出发点&#xff0c;使其在应用于非结构化数据时性能很好。如今深度学习模型可以玩游戏&#xff0c;检测癌症&#xff0c;和人类交谈&#xff0c;自动驾驶。 深度学习变得强大的同…

java多线程系列:通过对战游戏学习CyclicBarrier

CyclicBarrier是java.util.concurrent包下面的一个工具类&#xff0c;字面意思是可循环使用&#xff08;Cyclic&#xff09;的屏障&#xff08;Barrier&#xff09;&#xff0c;通过它可以实现让一组线程到达一个屏障&#xff08;也可以叫同步点&#xff09;时被阻塞&#xff0…

Wi-Fi 6到底有什么特别?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 甜草莓责编 | 阿秃▋ 什么是Wi-Fi 6 &#xff1f;Wi-Fi 6&#xff0c;是Wi-Fi联盟给IEEE Std. P802.11ax起的别名。众所周知&#xff0c;以前我们的Wi-Fi都是叫作802.11a/b/n/g/ac/ax之类的名字。这种命名方式实在容易让人…

matlab直流电机pid调速仿真,直流电机双闭环PID调速系统仿真设计

目录直流电机双闭环PID调速系统仿真1 转速、电流双闭环直流调速系统的组成及工作原理2 双闭环调速系统的动态数学模型3 调节器的设计3.1 电流调节器的设计3.2 转速调节器的设计4 搭建模型5 参数计算5.1 参数的直接计算5仿真具体参数6 仿真结果7 结束语8 参考文献摘要在工程的应…

【小技巧】桌面图标出现蓝色问号的怎么办?

【背景】 今天因为要联调前端所以用SVN更新了一下前端的代码&#xff0c;结果没想到桌面图标全部变成了带着蓝色问号的&#xff0c;吓了自己一跳。查了一下之后顺利解决了&#xff0c;不过以防万一记录一下解决方法。 【内容】 解决步骤&#xff1a;首先确定是SVN的问题导致了…

恒强制版系统980_速来围观 | 恒强制版小图高级功能讲解

点击蓝字关注我们 Spring comes小图是用自定义的动作来定义使用者色码(120-183)。小图的主要构成如下图&#xff1a;1. 模块色数属性模块色数有如下规则&#xff1a;(1) 小于100(一般填1)的小图为普通小图【980修改】&#xff1b;(2) 小于200大于100(一般填101)的小图为提花小图…

读懂这篇文章,你的阿里技术面就可以过关了 | Apache RocketMQ 101

在美国的大学课程中&#xff0c;101是所有课程中的第一门&#xff0c;是新生入学后的必修课程。阿里巴巴中间件技术专家刘振东在上周的Apache RocketMQ开发者沙龙北京站的活动上&#xff0c;进行了主题为《ApacheRocketMQ 101》的分享&#xff0c;帮助开发者从0开始学习 Apache…

Nacos 计划发布v0.2版本,进一步融合Dubbo和SpringCloud生态

在近期的Aliware Open Source 成都站的活动上&#xff0c;阿里巴巴高级工程师邢学超&#xff08;于怀&#xff09;分享了Nacos v0.2的规划和进度&#xff0c;并对Nacos v0.3的控制台进行了预览。Nacos v0.2将进一步融入Duboo和Spring Cloud生态&#xff0c;帮助开发者更好的在微…