Redisson可重入锁原理

news2025/2/26 22:20:12

微信公众号访问地址:Redisson可重入锁原理

推荐文章:

    1、使用原生Redis命令实现分布式锁

​    2、为什么引入Redisson分布式锁?

    3、SpringBoot整合多数据源,并支持动态新增与切换(详细教程)

    4、SpringBoot统一标准响应格式及异常处理

   5、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据

一、Redisson可重入锁原理

    1、可重入:利用hash结构记录线程id和重入次数。

    2、可重试:利用信号量和PubSub功能实现等待、唤醒,获取

锁失败的重试机制。

    3、超时续约:利用watchDog,每隔一段时间(releaseTime

/3),重置超时时间。

      Redisson提供的分布式锁是可重入的,它使用的是Hset命令和Hash数据结构。

      调用redisson.lock()方法会在redis中存储一个hash数据结构,key为锁的名称,value中的field为当前操作的线程id,value为锁重入的次数。

代码测试:

private  RLock rLock=null;    @ApiOperation(value="测试分布式锁的可重入锁原理", notes="testRedisson02")    @GetMapping("/testRedisson02")    public String testRedisson02() throws InterruptedException {        //1、获取锁(可重入),并指定锁的名称        rLock=redissonClient.getLock("lock:testRedisson02");        //2、尝试获取锁,参数分别是:waitTime:获取锁的最大等待时间(期间会重试)        // leaseTime:锁自动释放时间  TimeUnit:时间单位        //tryLock(long waitTime, long leaseTime, TimeUnit unit)        boolean isLock=rLock.tryLock(1,100, TimeUnit.SECONDS);        //3、判断锁获取成功及释放        if(isLock){            try {                log.info("执行正常的业务02......");                this.testRedisson03();            }catch (Exception e){                log.info("锁获取异常02e:"+e);            }finally {                //锁未关闭,则手动释放锁                if(rLock.isLocked()){                    rLock.unlock();                    log.info("释放锁成功02");                }            }        }        return "true";    }
    public void testRedisson03() throws InterruptedException {        //2、尝试获取锁,参数分别是:waitTime:获取锁的最大等待时间(期间会重试)        // leaseTime:锁自动释放时间  TimeUnit:时间单位        //tryLock(long waitTime, long leaseTime, TimeUnit unit)        boolean isLock=rLock.tryLock(1,100, TimeUnit.SECONDS);        //3、判断锁获取成功及释放        if(isLock){            try {                log.info("执行正常的业务03......");            }catch (Exception e){                log.info("锁获取异常03e:"+e);            }finally {                //锁未关闭,则手动释放锁                if(rLock.isLocked()){                    rLock.unlock();                    log.info("释放锁成功03");                }            }        }    }

输出结果:

具体分析如下:

        在上面的testRedisson02方法中,当外层testRedisson02方法加锁之后,会获取当前的线程标识存入field字段,并将value+1;当内层testRedisson03方法再次加这个锁,会先判断当前线程与field中存的线程是否是一样的,如果是一样的,value+1;此时value为2。如果要解锁,先要判断锁是否是自己的(比对key和field字段),如果是,则value-1。

获取锁的Lua脚本源码:

return evalWriteAsync(getName(), LongCodec.INSTANCE, command,                "if (redis.call('exists', KEYS[1]) == 0) then " +                        "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +                        "redis.call('pexpire', KEYS[1], ARGV[1]); " +                        "return nil; " +                        "end; " +                        "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +                        "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +                        "redis.call('pexpire', KEYS[1], ARGV[1]); " +                        "return nil; " +                        "end; " +                        "return redis.call('pttl', KEYS[1]);",

释放锁的Lua脚本源码

                return evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
                "if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +
                        "return nil;" +
                        "end; " +
                        "local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +
                        "if (counter > 0) then " +
                        "redis.call('pexpire', KEYS[1], ARGV[2]); " +
                        "return 0; " +
                        "else " +
                        "redis.call('del', KEYS[1]); " +
                        "redis.call('publish', KEYS[2], ARGV[1]); " +
                        "return 1; " +
                        "end; " +
                        "return nil;",

二、总结

1、不可重入Redis分布式锁:

    原理:利用setnx的互斥性;利用ex避免死锁;释放锁时判

断线程标识。 

    缺陷:不可重入、无法重试、锁超时失效。

2、可重入的Redis分布式锁:

    原理:利用hash结构,记录线程标示和重入次数;利用

watchDog延续锁时间;利用信号量控制锁重试等待。

    缺陷:redis宕机引起锁失效问题。--主从一致性问题

3、RedissonmultiLock:

    原理:多个独立的Redis节点,必须在所有节点都获取重入

锁,才算获取锁成功。

    缺陷:运维成本高、实现复杂。

更多详细资料,请关注个人微信公众号或搜索“程序猿小杨”添加。

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

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

相关文章

RDMA在典型场景下的技术应用分析与探索

本文首发于:RDMA在典型场景下的技术应用分析与探索 1.业务适配RDMA类型 RDMA传输的适配,从业务场景的使用角度来看,大致可分为如下几种类型。 场景一:机器学习、分布式存储等场景,使用社区成熟的方案,如在…

Linux之命名管道简单模拟进程间通信

Linux之命名管道简单模拟进程间通信 ​ ​ 文章目录 Linux之命名管道简单模拟进程间通信1.引言2.具体实现2.1服务端(Server.cc)2.2客户端(Client.cc) 3.结果 1.引言 ​ 首先,管道是一种半双工的单向进程间通信方式,也就是说它只能进行一边读一边写的…

【236. 二叉树的最近公共祖先】

目录 1.题目描述2.算法思路2.1算法思路12.2算法思路2 3.代码实现3.1代码实现13.2 代码实现2 1.题目描述 2.算法思路 2.1算法思路1 2.2算法思路2 思想很简单,但是最难的是怎么用栈来记录q、p的路线。所以下面才是关键。 3.代码实现 3.1代码实现1 class Solution…

Java训练五

一、跳动的心脏 心脏是动物的重要器官,不断跳动的心脏意味着鲜活的生命力。现在创建一个人类,把心脏类设计为人类里面的一个成员内部类。心脏类有一个跳动的方法,在一个人被创建时,心脏就开始不断地跳动。 package haha; publi…

「2024」预备研究生mem-相似三角形常规应用

一、相似三角形&常规应用 二、 课后习题

Vue2使用easyplayer

说一下easyplayer在vue2中的使用&#xff0c;vue3中没测试&#xff0c;估计应该差不多&#xff0c;大家可自行验证。 安装&#xff1a; pnpm i easydarwin/easyplayer 组件封装 习惯性将其封装为单独的组件 <template><div class"EasyPlayer"><e…

20230811在WIN11下使用python3批量将中英文的SRT格式的字幕合并

20230811在WIN11下使用python3批量将中英文的SRT格式的字幕合并 2023/8/11 8:35 缘起&#xff1a;将google翻译成为的简体中文字幕和剪影/RP2023直接通过语音OCR获取的SRT格式的英文字幕合并成为中英文的字幕&#xff01; 由于已经解决了UTF8的编码问题&#xff0c;ANSI/GBK编码…

Vue CLI 2.x搭建vue(目录最全分析)

一、vue-cli介绍 vue-cli是一个用于快速搭建vue项目的 脚手架。 二、vue-cli安装、更新 安装过nodeJs 、cnpm 后&#xff0c;全局安装vue-cli&#xff08;以后其他项目可直接使用&#xff09;&#xff1a; cnpm install -g vue-cli 查看安装成功否&#xff08;有版本号就是…

如何有效提高开发团队的开发效率?

提高生产力的实际因素之一是雇用为您的组织具有最高效率的开发人员。公司经理和人力资源管理最好雇用高效、有创造力和具有陡峭学习能力的员工。您将了解管理和领导力、战略规划、设定业务目标和建立工作满意度将如何提高组织中开发人员团队的生产力。 改进项目管理 提高团队…

mysql事务处理

一.抛出问题: 二. 事务: 1.本质:把多个操作,打包成一个操作完成. 2.原子性:多个操作,要么全部执行成功,要么一个都不执行(回滚). 3.回滚(rollback)机制:执行到中间出错了,自动把执行成功的操作还原到最初没有执行的样子. 实现回滚:把事务中每个执行的操作记录下来,如果要回…

还有人不知道这款网页版地理空间数据管理平台?赶紧来试试吧

四维轻云是一款网页版地理空间数据管理平台&#xff0c;用户能够在线管理、浏览及分享倾斜模型(.osgb)、激光点云(.las)、正射影像(dom)、数字高程模型(dem)等数据。目前&#xff0c;平台具有数据管理、场景编辑、空间测量、团队协作、加密分享、素材库等功能。 项目管理 四维…

13.1.1 翻转裁减,改变颜色,结合多种图像增广方法进行图像增广

一.图像增广的好处 随机改变训练样本可以减少模型对某些属性的依赖,从而提高模型的泛化能力。 裁剪图像可以减少模型对于对象出现位置的依赖 以不同的方式裁剪图像,使感兴趣的对象出现在不同的位置,减少模型对于对象出现位置的依赖 调整亮度、颜色等因素可以降低模型对颜色…

工业RFID识别技术,助力企业实现智能制造新高度!

RFID技术是一种无线通信技术&#xff0c;通过射频信号在读写器和射频标签之间进行数据交互&#xff0c;实现物体的自动识别和数据传输。随着科技的不断进步&#xff0c;RFID工业识别技术在智能制造领域扮演着越来越重要的角色。 RFID在智能制造中能解决什么问题&#xff1f; 物…

使用雅克比矩阵计算Lorenz的lyapunov exponent图谱

赋个初值看看: 我们使用雅克比矩阵计算lyapunov exponent图谱看看: matlab代码如下: clear; %% ===========初始化输入============== yinit = [0.1,0.1,0.1]; orthmatrix = [1 0 0;0 1 0;0 0 1];y = zeros(12,1); y(1:3) = yinit; y(4:12) = orthmatrix;mod = zeros(3,1…

c++QT文件操作

1 介绍 QT的文件操作来源于其抽象基类QIODevice&#xff0c;中用于处理输入输出设备。提供了统一的接口来处理不同类型的数据源&#xff0c;如文件、套接字、缓冲区等。QIODevice 主要用于读取和写入数据&#xff0c;无论数据来自何种源头&#xff0c;都可以通过 QIODevice 统一…

用 oneAPI 实现 AI 欺诈检测:一款智能图像识别工具

简介 虚假图像和视频日益成为社交媒体、新闻报道以及在线内容中的一大隐患。在这个信息爆炸的时代&#xff0c;如何准确地识别和应对这些虚假内容已经成为一个迫切的问题。为了帮助用户更好地辨别虚假内容&#xff0c;我开发了一款基于 oneAPI、TensorFlow 和 Neural Compress…

一文了解新能源电机国内主流供应商

作为新能源汽车核心三电系统之一的“电机”就好比燃油车的发动机一样&#xff0c;是车辆核心部件&#xff0c;但似乎消费者没太大关注这方面。今天我们给大家聊聊这个核心部件&#xff01; 一辆新能源汽车占生产成本最高的部件是动力电池&#xff0c;约占到30%左右&#xff0c…

ppt怎么压缩?试试这样压缩文件

当PPT文件体积过大时&#xff0c;打开的速度就会很慢&#xff0c;演示的时候刘程度也会受到影响&#xff0c;其次&#xff0c;现在很多平台对于上传的文件是有大小限制的&#xff0c;比如超过100M的文件就无法上传、发送等等&#xff0c;那么&#xff0c;怎么才能压缩PPT文件呢…

手撕HashMap源码

auth&#xff1a;虎 &#xff0c;2023年5月8日—???完。 前言&#xff1a; 最初在面试的时候&#xff0c;在个人栏第一条写了一句话“手撕HashMap”源码作为亮点&#xff0c;以下是曾经的学习笔记&#xff0c;目前来说不是很完整&#xff0c;有机会下次面试时候再补全吧~ 1…

python numpy数组水平和垂直合并

1 水平Horizontal合并 Horizontal:水平向右拉长 利用np.hstack()&#xff1a;原始数据size可以不一致 利用np.concatenate()&#xff1a;原始数据size可以不一致 import numpy as np # 三个一维数组 array1 np.array([1, 2, 3]) array2 np.array([4, 5, 6]) array3 np.ar…