SpringCloud 分布式锁Redisson锁的重入性与看门狗机制 高并发 可重入

news2025/7/26 8:19:14

可重入

Redisson 的锁支持 可重入性,这意味着同一个线程在获取锁后,如果再次尝试获取该锁,它可以成功地获得锁,而不会被阻塞。

  • 每次一个线程成功获取锁后,它的持有次数会增加。当线程再次获取该锁时,Redisson 会检查该线程是否已经持有锁。如果是,它会允许该线程再次获取锁,并将持有次数递增。
  • 每次释放锁时,持有次数会递减,直到持有次数变为零,锁才会被完全释放。

在这里插入图片描述

  public static void main(String[] args) {
        // 创建 Redisson 客户端配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379"); // 连接到本地 Redis 服务器
        RedissonClient redisson = Redisson.create(config);

        // 获取分布式锁
        RLock lock = redisson.getLock("accountLock");

        try {
            // 模拟账户操作的过程:先获取锁,进行第一次操作
            lock.lock();  //+1
            System.out.println("Lock acquired for the first time!");

            // 业务逻辑:扣款
            deductBalance(lock);

        } finally {
            // 释放锁:必须要释放与 lock.lock() 相同次数的 unlock() 才能完全释放锁
            lock.unlock();  //-1
            System.out.println("Lock released after first operation.");
        }
        
    }

    // 模拟业务逻辑:扣款操作
    private static void deductBalance(RLock lock) {
        // 业务逻辑需要在同一个线程中再次获取锁(模拟可重入性)
        lock.lock();//+1
        try {
            System.out.println("Lock acquired for the second time, performing deduct balance operation...");
            // 扣款逻辑,比如账户余额减少
            System.out.println("Balance deducted!");
        } finally {
            // 释放锁
            lock.unlock();//-1
            System.out.println("Lock released after deduct balance operation.");
        }
    }

当value值为0时就会释放锁。
在这里插入图片描述
这就是锁的可重入性。


看门狗机制

看门狗机制用于确保分布式系统中,锁或资源的持有者在预定时间内释放锁,否则看门狗会自动释放该锁,避免死锁等问题。帮助避免因某些异常(如程序崩溃或线程挂起)而导致锁被永久占用。

  • 自动续期:定期地自动刷新锁的过期时间。当锁被一个线程或进程持有时,会定期更新锁的 TTL(过期时间),以防止它被过期。即使持锁者在持有锁的过程中没有显式地释放锁,会确保锁不会在持有者不主动释放时过期,从而避免因过期造成的错误。

  • 自动解锁:如果持锁者超时或出现故障,会在检测到持锁者没有继续更新锁的超时时间后,自动释放锁,避免死锁。

  • 配置超时时间:可以与锁的过期时间和续期机制结合使用,可以通过配置来指定超时时间和自动续期的时间间隔。

在这里插入图片描述

相关源代码
尝试获取锁,如果不能获取锁,一直等待直到获取成功或者达到超时限制。中间部分涉及到锁的租期和超时处理,保证锁的可用性和避免死锁。interruptibly 参数提供了是否支持中断等待的选项。

private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException {
    // 获取当前线程的ID,用于标识是哪一个线程请求锁
    long threadId = Thread.currentThread().getId();

    // 尝试获取锁,并获得锁的剩余有效时间 ttl
    Long ttl = this.tryAcquire(-1L, leaseTime, unit, threadId);

    // 如果成功获得锁(ttl != null),则进入锁处理逻辑
    if (ttl != null) {
        // 订阅当前线程的锁操作,返回一个 RFuture 对象,用于后续的异步操作
        RFuture<RedissonLockEntry> future = this.subscribe(threadId);

        // 根据 interruptibly 参数决定同步执行订阅操作
        if (interruptibly) {
            // 如果需要响应中断,使用带中断支持的同步方法
            this.commandExecutor.syncSubscriptionInterrupted(future);
        } else {
            // 如果不需要响应中断,直接使用同步方法
            this.commandExecutor.syncSubscription(future);
        }

        try {
            // 启动一个无限循环来持续尝试获取锁
            while (true) {
                // 每次进入循环时,重新尝试获取锁的剩余时间 ttl
                ttl = this.tryAcquire(-1L, leaseTime, unit, threadId);

                // 如果 ttl 为 null,表示锁已经过期或无法获取,跳出循环
                if (ttl == null) {
                    return;
                }

                // 如果 ttl >= 0L,表示可以继续持有锁
                if (ttl >= 0L) {
                    try {
                        // 尝试在 ttl 指定的时间内获取 latch
                        ((RedissonLockEntry) future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);
                    } catch (InterruptedException var13) {
                        // 如果在获取 latch 时发生 InterruptedException,则根据 interruptibly 变量决定是否抛出异常
                        if (interruptibly) {
                            // 如果需要响应中断,抛出 InterruptedException
                            throw var13;
                        }

                        // 如果不需要响应中断,尝试继续获取 latch
                        ((RedissonLockEntry) future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);
                    }
                } else if (interruptibly) {
                    // 如果 ttl 为负值并且需要响应中断,调用 acquire 方法阻塞直到获取锁
                    ((RedissonLockEntry) future.getNow()).getLatch().acquire();
                } else {
                    // 如果 ttl 为负值并且不需要响应中断,调用 acquireUninterruptibly 方法阻塞直到获取锁
                    ((RedissonLockEntry) future.getNow()).getLatch().acquireUninterruptibly();
                }
            }
        } finally {
            // 最终,取消订阅,释放资源
            this.unsubscribe(future, threadId);
        }
    }
}

  • 自动续期:通过 ttl 值和 latch.tryAcquire 方法,锁的超时时间会在持有锁的线程未释放锁的情况下自动延长,避免锁超时。
  • 避免死锁:如果线程因为异常等原因没有释放锁,看门狗机制会确保锁最终被释放。

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

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

相关文章

02 APP 自动化-Appium 运行原理详解

环境搭建见 01 APP 自动化-环境搭建 文章目录 一、Appium及Appium自动化测试原理二、Appium 自动化配置项三、常见 ADB 命令四、第一个 app 自动化脚本 一、Appium及Appium自动化测试原理 Appium 跨平台、开源的 app 自动化测试框架&#xff0c;用来测试 app 应用程序&#x…

由docker引入架构简单展开说说技术栈学习之路

想象一下&#xff0c;你开了一家线上小卖部&#xff08;单机版&#xff09;&#xff0c;突然爆单了怎么办&#xff1f;别急&#xff0c;技术架构的升级打怪之路&#xff0c;可比哆啦A梦的口袋还神奇&#xff01; 第1关&#xff1a;单枪匹马的创业初期&#xff08;单机架构&…

linux 1.0.5

环境变量到底是什么 也就是windows上面的环境变量 就是这个东东&#xff0c;用户变量和系统变量&#xff0c;那这些到底是啥呢&#xff1f; 主包只是用过&#xff0c;配置来配置去的&#xff0c;就是不知道是啥意思 windows上面的环境变量 windows的ls命令是dir 输入calc可有…

强化学习的前世今生(五)— SAC算法

书接前四篇 强化学习的前世今生&#xff08;一&#xff09; 强化学习的前世今生&#xff08;二&#xff09; 强化学习的前世今生&#xff08;三&#xff09;— PPO算法 强化学习的前世今生&#xff08;四&#xff09;— DDPG算法 本文为大家介绍SAC算法 7 SAC 7.1 最大熵强化…

生成对抗网络(GAN)基础原理深度解析:从直观理解到形式化表达

摘要 本文详细解析 生成对抗网络&#xff08;GAN&#xff09; 的 核心原理&#xff0c;从通俗类比入手&#xff0c;结合印假钞与警察博弈的案例阐述生成器 与 判别器 的对抗机制&#xff1b;通过模型结构示意图&#xff0c;解析 噪声采样、样本生成 及判别流程&#xff1b;基于…

【GitHub开源AI精选】WhisperX:70倍实时语音转录、革命性词级时间戳与多说话人分离技术

系列篇章&#x1f4a5; No.文章1【GitHub开源AI精选】LLM 驱动的影视解说工具&#xff1a;Narrato AI 一站式高效创作实践2【GitHub开源AI精选】德国比勒费尔德大学TryOffDiff——高保真服装重建的虚拟试穿技术新突破3【GitHub开源AI精选】哈工大&#xff08;深圳&#xff09;…

华为OD机试真题——文件目录大小(2025 A卷:100分)Java/python/JavaScript/C++/C语言/GO六种语言最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《文件目录大小》: 目录 题…

消费者行为变革下开源AI智能名片与链动2+1模式S2B2C商城小程序的协同创新路径

摘要&#xff1a;在信息爆炸与消费理性化趋势下&#xff0c;消费者从被动接受转向主动筛选&#xff0c;企业营销模式面临重构挑战。本文提出开源AI智能名片与链动21模式S2B2C商城小程序的协同创新框架&#xff0c;通过AI驱动的精准触达、链动裂变机制与S2B2C生态赋能&#xff0…

软考 系统架构设计师系列知识点之杂项集萃(78)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;77&#xff09; 第139题 以下关于软件测试工具的叙述&#xff0c;错误的是&#xff08;&#xff09;。 A. 静态测试工具可用于对软件需求、结构设计、详细设计和代码进行评审、走查和审查 B. 静…

如何解决MySQL Workbench中的错误Error Code: 1175

错误描述&#xff1a; 在MySQL Workbench8.0中练习SQL语句时&#xff0c;执行一条update语句&#xff0c;总是提示如下错误&#xff1a; Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY columnTo disab…

Docker 镜像(或 Docker 容器)中查找文件命令

在 Docker 镜像&#xff08;或 Docker 容器&#xff09;中运行如下两个命令时&#xff1a; cd / find . -name generate.py它们的含义如下&#xff0c;我们来一行一行详细拆解&#xff0c;并结合例子讲解&#xff1a; ✅ 第一行&#xff1a;cd / ✅ 含义 cd 是“change dire…

MySQL进阶篇(存储引擎、索引、视图、SQL性能优化、存储过程、触发器、锁)

MySQL进阶篇 存储引擎篇MySQL体系结构存储引擎简介常用存储引擎简介存储引擎的选择 索引篇索引简介索引结构(1)BTree索引(2)hash索引 索引分类索引语法SQL性能分析指标(1)SQL执行频率(2)慢查询日志(3)profile详情(4)explain或desc执行计划 索引使用引起索引的失效行为SQL提示覆…

BugKu Web渗透之game1

启动场景&#xff0c;打开网页如下&#xff1a; 是一个游戏。 步骤一&#xff1a; 右键查看源代码也没有发现异常。 步骤二&#xff1a; 点击开始游戏来看看。 结果他是这种搭高楼的游戏。我玩了一下子&#xff0c;玩到350分就game over。 之后就显示游戏结束&#xff0c;如…

Axure设计案例——科技感渐变柱状图

想让你的数据展示瞬间脱颖而出&#xff0c;成为众人瞩目的焦点吗&#xff1f;快来看看这个 Axure 设计的科技感渐变柱状图案例&#xff01;科技感设计风格以炫酷的渐变色彩打破传统柱状图的单调&#xff0c;营造出一种令人惊叹的视觉盛宴。每一个柱状体都仿佛蕴含着无限能量&am…

互联网大厂智能体平台体验笔记字节扣子罗盘、阿里云百炼、百度千帆 、腾讯元器、TI-ONE平台、云智能体开发平台

互联网大厂 字节扣子、阿里云百炼、百度千帆 、腾讯元器、TI-ONE平台、云智能体开发平台 体验 开始动手 了解 智能体&#xff0c;发现已经落后时代太远 光头部互联网大厂对开 公开的平台就已经这么多&#xff0c;可以学习和了解&#xff0c;相关的信息 整理了对应的平台地址…

深入解析ReactJS中JSX的底层工作原理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…

NodeMediaEdge任务管理

NodeMediaEdge任务管理 简介 NodeMediaEdge是一款部署在监控摄像机网络前端中&#xff0c;拉取Onvif或者rtsp/rtmp/http视频流并使用rtmp/kmp推送到公网流媒体服务器的工具。 在未使用NodeMediaServer的情况下&#xff0c;或是对部分视频流需要单独推送的需求&#xff0c;也可…

SpringBoot集成第三方jar的完整指南

原文地址&#xff1a;https://blog.csdn.net/weixin_43826336/article/details/141640152?ops_request_misc%257B%2522request%255Fid%2522%253A%25227d4118ef2d572ba4428caf83f1d2bb28%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id7d4118…

前端基础之《Vue(18)—路由知识点》

一、两种路由模式 1、hash路由 &#xff08;1&#xff09;url中有#号&#xff0c;背后是监听onhashchange事件 &#xff08;2&#xff09;hash路由部署上线不会出现404问题&#xff0c;背后是基于history api实现的 2、history路由 &#xff08;1&#xff09;url中没有#号 &a…

014校园管理系统技术解析:构建智慧校园管理平台

校园管理系统技术解析&#xff1a;构建智慧校园管理平台 在教育信息化快速发展的当下&#xff0c;校园管理系统成为提升学校管理效率、优化校园服务的重要工具。该系统集成院校管理、投票管理等多个核心模块&#xff0c;面向管理员、用户和院内管理员三种角色&#xff0c;通过…