Redis实战(使用Scan,Lua脚本,一次扣多个库存,多线程并发使用,并发获取分布式锁,BItMap实现签到和在线统计)

1.使用Scan

2.lua脚本操作Redis

一次扣减一个商品库存

一次扣减多个商品的库存

 @Testvoid test100() {String  key = "product.1";stringRedisTemplate.opsForValue().set("product.1","10");stringRedisTemplate.opsForValue().set("product.2","20");stringRedisTemplate.opsForValue().set("product.3","30");}@Test //模拟下单扣多个商品库存void test3() {ArrayList<FreezeProduct> freezeProducts = CollUtil.newArrayList(new FreezeProduct().setProductId(1).setQty(5),new FreezeProduct().setProductId(2).setQty(5),new FreezeProduct().setProductId(3).setQty(5));StringBuilder sb = new StringBuilder();// 1. 我要知道需求量是多少 ,还要知道是哪个keysb.append("  local myTable = {} ");// 2. 我要判断目前的库存量是否满足需求量sb.append(" local redisQtys = redis.call('mget',unpack(KEYS)) ");sb.append(" for i = 1, #KEYS  do ");sb.append("    if tonumber(ARGV[i]) > tonumber(redisQtys[i])  then ");sb.append("        myTable[#myTable + 1] = KEYS[i] .. '=' .. redisQtys[i]  ");sb.append("     end ");sb.append(" end ");// 3. myTable 有元素  return  ,没有元素 就扣sb.append(" if #myTable > 0 then  ");sb.append("  return myTable ");sb.append(" end ");sb.append(" for i = 1 , #KEYS do");sb.append("  redis.call('decrby',KEYS[i],ARGV[i]) ");sb.append(" end ");sb.append(" return {} ");// 返回 : 如果不足  集合 ,如果 满足:空集合RedisScript<List> script = RedisScript.of(sb.toString(),List.class);List<String> keys = freezeProducts.stream().map(it -> "product." + it.getProductId()).collect(Collectors.toList());Object[] qtys = freezeProducts.stream().map(it -> it.getQty() + "").toArray();List list = stringRedisTemplate.execute(script, keys,qtys);if(list.isEmpty()){System.out.println(StrUtil.format("下单成功"));} else {System.out.println(StrUtil.format("下单失败,{}",list));}}

3.模拟多线程并发使用Decrby


public class DecrByDemo {@Resource(name = "redisTemplate")private ValueOperations<String, Integer> valueOperations;private static final String key = "product.01";public void test() {valueOperations.set(key, 5);ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {executorService.execute(() -> {Integer value = valueOperations.get(key);if (value >= 1) {valueOperations.set(key, value - 1);System.out.println(StrUtil.format("线程{} -> 扣减成功", Thread.currentThread().getName()));} else {System.out.println(StrUtil.format("线程{} -> 扣减失败", Thread.currentThread().getName()));}});}System.in.read();}public void test2() {valueOperations.set(key, 5);ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {executorService.execute(() -> {Long value = valueOperations.decrement(key);if (value >= 0) {System.out.println(StrUtil.format("线程{} -> 扣减成功,剩余库存{}", Thread.currentThread().getName(),value));} else {System.out.println(StrUtil.format("线程{} -> 扣减失败", Thread.currentThread().getName()));}});}System.in.read();}
}

4.模拟多线程并发获取分布式锁SetNX

@Component
public class SetNxDemo {@Resource(name = "redisTemplate")private ValueOperations<String, String> valueOperations;public void test() throws InterruptedException {//出入库场景 ExecutorService executorService = Executors.newCachedThreadPool();for(int i =1; i<6;i++){executorService.execute(()->{while (true){// 获取分布式锁Boolean b = valueOperations.setIfAbsent("wms.io.locker",  DateUtil.now());if(b){System.out.println(Thread.currentThread().getName() + " 获取到了分布式锁" );ThreadUtil.safeSleep(5000); //模拟业务操作stringRedisTemplate.delete("wms.io.locker");break;} else {System.out.println(Thread.currentThread().getName() + " 获取锁失败,睡眠2s" );ThreadUtil.safeSleep(2000);}}});}System.in.read();}}

5.BitMap

签到

@Component
public class BitMapDemo {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private final  String key ="sign.2024.zhouxingxing";public void test(){//设置签到stringRedisTemplate.opsForValue().setBit(key,2,true);stringRedisTemplate.opsForValue().setBit(key,85,true);//获取周星星同学的签到天数RedisCallback<Long> callback = connection -> { return  connection.bitCount(key.getBytes(),0,365);};Long count = stringRedisTemplate.execute(callback);//打印周星星2024年签到天数System.out.println("周星星2024年一共签到天数:"+count);}
}

模拟在线统计

@Component
public class BitMapDemo {@Resource(name = "redisTemplate")private ValueOperations valueOperations;@Autowiredprivate StringRedisTemplate redisTemplate;private static final int user01 = 1;private static final int user02 = 2;private static final int user03 = 3;private static String key20220601 = "20200601";private static String key20220602 = "20200602";private static String key20220603 = "20200603";private static String saveKey = "q1";public void test() {valueOperations.setBit(key20220601, user01, true);valueOperations.setBit(key20220601, user02, true);valueOperations.setBit(key20220602, user02, true);valueOperations.setBit(key20220603, user01, true);valueOperations.setBit(key20220603, user03, true);//1. 一直在线人数统计//2. 时间段活跃用户RedisCallback<Long> callback = connection -> {return connection.bitOp(RedisStringCommands.BitOperation.AND, saveKey.getBytes(),key20220601.getBytes(), key20220602.getBytes(), key20220603.getBytes());};Long value = redisTemplate.execute(callback);RedisCallback<Long> callback2 = connection -> {return connection.bitCount(saveKey.getBytes());};Long value2 = redisTemplate.execute(callback2);System.out.println(value2);}}

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

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

相关文章

在一个.NET Core项目中使用RabbitMQ进行即时消息管理

为了在一个.NET Core项目中使用RabbitMQ进行即时消息管理&#xff0c;以下是详细的全程操作指南&#xff0c;包括安装、配置、编写代码和调试使用。 一、安装RabbitMQ 1. 安装Erlang RabbitMQ依赖Erlang&#xff0c;因此需要先安装Erlang。 Windows: 下载并运行Erlang安装…

千亿数据-异地容灾-查询打印——MySQL大数据优化

1. 数据备份策略 - 定期全量备份&#xff1a;制定周期性的全量数据备份计划&#xff0c;确保数据的完整性。 - 增量备份&#xff1a;在全量备份之间进行增量备份&#xff0c;减少备份时间和存储空间。 2. 数据存储 - 分布式存储&#xff1a;利用分布式存储系统来存…

港科夜闻 | 香港科大颁授荣誉大学院士予五位杰出人士

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大颁授荣誉大学院士予五位杰出人士。香港科大9月24日向五位杰出人士颁授荣誉大学院士&#xff0c;他们分别为包弼德教授、简吴秋玉女士、高秉强教授、吴永顺先生及容永祺博士(按姓氏英文字母排序)。荣誉大学院士颁…

多无人机通信(多机通信)+配置ssh服务

目录 多机通信 设备 主从机通信设置 配置从机 配置主机 测试 正式启用 MAVROS通信 多机通信 多机通信是实现机器人编队的基础&#xff0c;通过网络搭建通信链路。我们这里用中心节点网络通信&#xff0c;所有数据需有经过中心节点&#xff0c;所以&#xff0c;中心节点…

C++黑暗迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> #include <cstdlib> #include <ctime> using namespace std; struct near {int i;int ia;int ix;int iy;int iwalk; }; v…

单片机长短按简单实现

单片机长短按简单实现 目录 单片机长短按简单实现1 原理2 示例代码2.1 按键实现 3 测试log4 其他实现方式 1 原理 按键检测和处理的步骤如下&#xff1a; 1&#xff1a;定时扫描按键&#xff08;使用定时器定时扫描&#xff0c;也可以用软件延时或者系统心跳之类的方式&#…

信息安全工程师(21)安全协议

前言 安全协议是建立在密码体制基础上的一种交互通信协议&#xff0c;它运用密码算法和协议逻辑来实现认证、密钥分配、数据机密性、完整性和抗否认性等安全目标。 一、定义与目的 安全协议旨在确保网络环境中信息交换的安全性&#xff0c;通过密码技术和协议逻辑来保护数据的机…

AIGC入门:Comfyui整合包,解压即用!

整合包获取方式放在文末了 今天给大家分享的Comfyui的整合包&#xff0c;无需复杂的操作&#xff0c;解压即可使用。 整合包已经打包好了&#xff0c;获取方式放在文末&#xff0c;需要的朋友可以自行领取哦。 什么是Comfyui ComfyUI采用节点式的操作方式&#xff0c;这种方…

240922-局域网内通过SSH与SFTP访问RHEL服务器

要通过SFTP&#xff08;安全文件传输协议&#xff09;在局域网内访问一台RHEL服务器&#xff0c;您需要确保以下步骤都已经正确完成&#xff1a; A. 在RHEL服务器上配置SFTP服务 RHEL默认通过sshd服务提供SFTP功能&#xff0c;SFTP使用SSH协议进行文件传输&#xff0c;因此需要…

DarkLabel2.4版本导入MOT17数据集

目录 背景导入效果MOT17数据集说明DarkLabel导入视频导入gt文件 背景 做目标追踪&#xff0c;目前找了一圈开源工具&#xff0c;发现DarkLabel还是很好用的&#xff0c;提供自动目标跟踪&#xff0c;标注很方便。 由于目标追踪我用的是bytetrack&#xff0c;官网是用mot17数据…

Qt开发技巧(十)新版随机数,模拟鼠标移动,QTextEdit卡死问题,函数返回值,参数结构化,选项卡控件,窗体属性

继续讲一些Qt开发中的技巧操作&#xff1a; 1.新版随机数 Qt中有自己的随机数取值方法&#xff0c;Qt5.10以前使用qsrand方法&#xff0c; Qt5.10以后提供了新的类 QRandomGenerator QRandomGenerator64 管理随机数&#xff0c;使用更方便&#xff0c;尤其是取某个区间的随机数…

AtCoder Regular Contest 156 C. Tree and LCS(思维题 构造 数学归纳法)

题目 构造一个排列p&#xff0c; 使得对于任意树上路径&#xff0c; 求该路径上的点(x1,...,xk)和对应排列上的点(Px1,...,Pxk)的最长公共子序列都得到一个值&#xff0c; 称为相似值 现在想令任意树上路径的相似值的最大可能长度最小&#xff0c; 最小化前提下&#xff0…

Unity 网格的细节级别 (LOD) 学习

Unity LOD学习 文档 网格的细节级别 (LOD) https://docs.unity.cn/cn/2020.3/Manual/LevelOfDetail.html在项目中使用 自动设置导入 文档&#xff1a; https://docs.unity.cn/cn/2020.3/Manual/importing-lod-meshes.html可以在外部 3D 应用程序中创建具有不同细节级别的网…

【机器学习(十)】时间序列案例之月销量预测分析—Holt-Winters算法—Sentosa_DSML社区版

文章目录 一、Holt-Winters算法原理(一) 加法模型(二) 乘法模型(三) 阻尼趋势 二、Holt Winters算法优缺点优点缺点 三、Python代码和Sentosa_DSML社区版算法实现对比(一) 数据读入和统计分析(二) 数据预处理(三) 模型训练和模型评估(四) 模型可视化 四、总结 一、Holt-Winters…

【bug fixed】hexo d的时候Spawn failed

在执行hexo d部署的时候&#xff0c;遇到报错&#xff1a; % hexo d INFO Validating config INFO Deploying: git INFO Clearing .deploy_git folder... INFO Copying files from public folder... INFO Copying files from extend dirs... [main 8e89088] Site updated…

VS开发C++项目常用基础属性配置

这篇文件简单讨论一下visual studio中项目属性的常用基础配置。 1.输出目录&#xff1a;项目目标文件生成位置。 2.中间目录&#xff1a;项目生成的中间文件所在的位置。 3.目标文件名&#xff1a;项目生成目标文件名称。 4.附加包含目录&#xff1a;三方库等头文件所在的位…

【Python】探索 Graphene:Python 中的 GraphQL 框架

人们常说挣多挣少都要开心&#xff0c;这话我相信&#xff0c;但是请问挣少了怎么开心&#xff1f; 随着现代 Web 应用对数据交互需求的不断增长&#xff0c;GraphQL 作为一种数据查询和操作语言&#xff0c;越来越受到开发者的青睐。Graphene 是 Python 语言中实现 GraphQL 的…

工业缺陷检测——Windows 10本地部署AnomalyGPT工业缺陷检测大模型

0. 引言 在缺陷检测中&#xff0c;由于真实世界样本中的缺陷数据极为稀少&#xff0c;有时在几千甚至几万个样品中才会出现一个缺陷数据。因此&#xff0c;以往的模型只需在正常样本上进行训练&#xff0c;学习正常样品的数据分布。在测试时&#xff0c;需要手动指定阈值来区分…

vite 底层解析

vite 目前大多数框架的前端构建工具都已经被vite取代&#xff0c;相信你已经使用过vite了。可是在使用过程中&#xff0c;vite对我来说一直是模糊的&#xff0c;现在就来一探究竟&#xff0c;为啥它更好&#xff1f; 接下来我将为从以下几点出发&#xff0c;究其原理 一、原生…

Redis篇(应用案例 - 商户查询缓存)

目录 一、什么是缓存? 二、为什么要使用缓存 三、如何使用缓存 四、添加商户缓存 1. 缓存模型和思路 2. 代码如下 五、缓存更新策略 1. 内存淘汰 2. 超时剔除 3. 主动更新 六、数据库缓存不一致解决方案 1. 数据库缓存不一致解决方案 2. 数据库和缓存不一致采用什…