模仿看门狗写个简单的分布式锁demo

    public void tryLock() {
//        判断key是否存在,存在则返回 用户信息
//        不存在则生成key,将信息(用户名,用户id,线程名)放入TYuanGong pcCurrentUser = TisUtils.getPcCurrentUser();String name = Thread.currentThread().getName();//=================================================// redis redis.call('exists', KEYS[1]) 存在为1 不存在为0//=================================================String xingMing = String.valueOf(pcCurrentUser.getXingMing());List<Object> resList = (List) redisTemplate.execute(new DefaultRedisScript<List>("local result = {};" +"if (redis.call('exists', KEYS[1]) == 0) " +"then " +"redis.call('hmset', KEYS[1], ARGV[1], ARGV[2], ARGV[3], ARGV[4], ARGV[5], ARGV[6]);" +"redis.call('expire', KEYS[1], 30);" +"result[1] = 1;" +"else " +"result[1] = redis.call('hget', KEYS[1],ARGV[1]);" +"end;" +"return result;", List.class), Arrays.asList(OrderPreArrangementService.LOCK_KEY),"userName", xingMing, "userId", pcCurrentUser.getGongHao(), "threadName", name);String res = String.valueOf(resList.get(0));if (!"1".equals(res)) {if (xingMing.equals(res)) {throw new RuntimeException("算力君正在快马加鞭cpu中,请耐心等待!");}throw new RuntimeException(String.format("算力被%s占用中,请稍后再试!", res));}
//        开启续期操作this.scheduleExpirationRenewal(name);}private static volatile ArrayList<String> threadNames = new ArrayList<>();private void scheduleExpirationRenewal(String threadName) {new Thread(new Runnable() {@Overridepublic void run() {Long res = 1l;if (threadNames.contains(threadName)) return;threadNames.add(threadName);// 判断value是当前线程才续期,否则返回0代表结束while (res == 1l) {try {Thread.currentThread().sleep(1000 * 10);} catch (InterruptedException e) {e.printStackTrace();}res = (Long) redisTemplate.execute(new DefaultRedisScript<Long>("if (redis.call('exists', KEYS[1]) == 1) " +"then " +"if (redis.call('hget', KEYS[1], ARGV[2]) == ARGV[1]) " +"then " +"redis.call('expire', KEYS[1], 30);" +"return 1;" +"else " +"return 0;" +"end;" +"else " +"return 0;" +"end;", Long.class), Arrays.asList(OrderPreArrangementService.LOCK_KEY), threadName, "threadName");}threadNames.remove(threadName);}}).start();}public void unLock() {redisTemplate.execute(new DefaultRedisScript("if (redis.call('exists', KEYS[1]) == 1) " +"then " +"if (redis.call('hget', KEYS[1], ARGV[2]) == ARGV[1]) " +"then " +"redis.call('del', KEYS[1]);" +"end;" +"end;", Boolean.class), Arrays.asList(OrderPreArrangementService.LOCK_KEY), Thread.currentThread().getName(), "threadName");}
    @GetMapping("/testThread2")public AjaxResult testThread2() {this.preArrangementService.tryLock();try {for (int i = 0; i < 10; i++) {System.out.println("主线程~~");Thread.currentThread().sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println("主线程结束,进行解锁");this.preArrangementService.unLock();}return null;}

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

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

相关文章

14、SpringCloud -- WebSocket 实时通知用户

目录 实时通知用户需求:代码:前端:后端:WebSocket创建 websocket-server 服务添加依赖:配置 yml 和 启动类:前端:后端代码:注意:测试:总结:实时通知用户 需求: 用户订单秒杀成功之后,对用户进行秒杀成功通知。 弹出个提示框来提示。 代码: 前端:

【设计模式】第11节:结构型模式之“装饰器模式”

一、简介 装饰器模式主要解决继承关系过于复杂的问题&#xff0c;通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外&#xff0c;装饰器模式还有一个特点&#xff0c;那就是可以对原始类嵌套使用多个装饰器。…

第5天:基础入门-资产架构amp;端口amp;应用amp;CDNamp;WAFamp;站库分离amp;负载均衡

第5天&#xff1a;基础入门-资产架构&端口&应用&CDN&WAF&站库分离&负载均衡 #知识点&#xff1a;1. 资产架构-端口&目录&插件接口&多站点&多应用 2. 番外安全-域名&服务器本身&服务厂商&管理人员 3. 考虑阻碍-站库分离&am…

Redis-使用java代码操作Redis

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这…

go语言 | grpc原理介绍(一)

参考 https://www.nowcoder.com/discuss/389810396381683712?sourceSSRsearch 这里是b站对应的csdn博客&#xff0c;比较详细的介绍grpc相关原理说明&#xff0c;首先是大概的一个流程图说明。 什么是 RPC &#xff1f; 远程过程调用&#xff08;RPC&#xff09;是计算机科…

[推荐]SpringBoot java实现文件/附件上传下载 服务器 数据库 拿来就用,简单实用

推荐一个思路非常简单又很实用的文件上传下载方式&#xff0c;代码十分简练&#xff0c;可以开箱即用&#xff0c;下面是使用到的一些工具类和业务代码&#xff1b; 1.文件上传实现 判断文件类型的工具类&#xff0c;一些使用到的实体类我会凡在文末&#xff0c;需要可以的自…

吴恩达《机器学习》4-1->4-5:多变量线性回归

一、引入多维特征 在多维特征中&#xff0c;我们考虑的不再是单一的特征&#xff0c;而是一组特征&#xff0c;例如房价模型中可能包括房间数、楼层等多个特征。这些特征将组成一个向量&#xff0c;表示为(&#x1d465;₁, &#x1d465;₂, . . . , &#x1d465;ₙ)&#x…

nodelist 与 HTMLCollection 的区别

原地址 https://cloud.tencent.com/developer/article/2013289 节点与元素 根据 W3C 的 HTML DOM 标准&#xff0c;HTML 文档中的所有内容都是节点&#xff1a; 整个文档是一个文档节点每个 HTML 元素是元素节点HTML 元素内的文本是文本节点每个 HTML 属性是属性节点注释是注…

ts 简易封装 axios,统一 API

文章目录 为什么要封装目标文件结构封装通用请求方法获得类型提示http 方法文件上传使用示例实例化post 请求类型提示文件上传 总结完整代码&#xff1a; 为什么要封装 axios 本身已经很好用了&#xff0c;看似多次一举的封装则是为了让 axios 与项目解耦。比如想要将网络请求…

视频增强和修复工具 Topaz Video AI mac中文版功能

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等。 使用Topaz Video AI非常简单&#xff0c…

突破防火墙的一种方法

当Linux防火墙阻止来自某个ip的数据时&#xff0c;它应该是根据ip数据报里“源IP地址”字段取得的对方ip吧&#xff0c;那对方就不能通过篡改“源IP地址”来绕过防火墙吗&#xff1f;NAT模式下的路由器就修改了这个字段。 但这样的话&#xff0c;攻击者是收不到服务器返回的数…

PHP获取域名地址,$_SERVER[]用法

一、PHP获取域名地址 $host $_SERVER[HTTP_HOST];二、PHP获取域名后面的所有字符 $host $_SERVER[REQUEST_URI];//https://www.baidu.com/md/?articleId134157878//输出 /md/?articleId134157878三、PHP获取服务器的IP $serverIP $_SERVER[SERVER_ADDR]; echo "服务…

学 Java 怎么进外企?

作者&#xff1a;**苍何&#xff0c;CSDN 2023 年 实力新星&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#…

麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器

原文链接&#xff1a;麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器 hello&#xff0c;大家好啊&#xff0c;今天给大家带来麒麟桌面操作系统软件仓库搭建的文章01-新创建软件仓库服务器&#xff0c;本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版本上搭建内网…

docker 下安装mysql8.0

在docker中查询mysql镜像 PS C:\Users\admin> docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation……

使用java代码操作Redis

一、Java连接Redis 二、Java操作Redis的常见类型数据存储 三、Redis中的项目应用

YOLOV8最简图像分类检测推理代码

安装YOLOV8 首先要去YOLOV8的官网安装库 YOLOV8官方网站 # Install the ultralytics package from PyPI pip install ultralytics安装opencv pip install opencv-pythonimport cv2 from ultralytics import YOLO# Load the YOLOv8 model model YOLO(yolov8n.pt)# Open the …

【Python_GraphicsView 学习笔记(一)】Graphics View框架的基本介绍

【Python_GraphicsView 学习笔记&#xff08;一&#xff09;】Graphics View框架的基本介绍 前言正文1、Graphics View框架简介2、Graphics View框架与QPainter类的区别3、Graphics View框架的三个组成部分4、场景QGraphicsScene类5、视图QGraphicsView类6、图形项QGraphicsIte…

深度学习_3 数据操作之线代,微分

线代基础 标量 只有一个元素的张量。可以通过 x torch.tensor(3.0) 方式创建。 向量 由多个标量组成的列表&#xff08;一维张量&#xff09;。比如 x torch.arange(4) 就是创建了一个1*4的向量。可以通过下标获取特定元素&#xff08;x[3]&#xff09;&#xff0c;可以通…

Vue3入门指南:零基础小白也能轻松理解的学习笔记

文章目录 创建项目开发环境项目目录模板语法属性绑定条件渲染列表渲染事件处理内联事件处理器方法事件处理器&#xff08;常用&#xff09; 事件参数获取 event 事件事件传参 事件修饰符阻止默认事件阻止事件冒泡 数组变化侦测变更方法替换一个数组 计算属性class 绑定单对象绑…