redis 单机锁 分布式锁

Redis:普通锁和分布式锁实现原理 Redis:普通锁和分布式锁实现原理 1、Redis单服务实例实现锁 实现锁有以下要求: (1)唯一性:一把锁只能存在一个实例; (2)无死锁:client操作超时自动释放; (3)安全性:只对当前client可操作; 唯一性:同一把锁有切只能有一个实例;假如A、B两个client同时有Key这把锁,A和B都有权限同时操作同一数据,那“锁”也就没有了意义,锁存在的意义就是避免同步操作; 无死锁:c... 阅读详情

单机锁:

多线程访问redis缓存时, 要保证数据同步,可以给redis里的数据加锁。 

加锁有两种方式, 一种是使用java 的关键字 synchronized , 一种是使用ReentratLock类。

synchronized加锁手段非常强硬,一旦锁住,除非块内程序执行完成,否则不开锁。其他线程想要访问就得一直等待。

而RenntraLock类的加锁方式比较温和。 一个线程使用RenntraLock去抢锁, 抢到了就执行代码, 抢不到可以在else中处理抢不到锁的代码。 还可以设置超时时间,抢不到的话,在指定的时间内继续抢,时间一到,则不再抢锁。 和synchronized不同,synchronized抢不到会一直抢,直到抢到才罢休。

RenntraLock代码示例:

        Lock lock = new ReentrantLock();
        if(lock.tryLock())
        {
            lock.lock();
            //业务逻辑
        }
        else
        {
            // 没有抢到线程的业务逻辑--放弃执行
            lock.unlock();
        }

synchronized代码示例:

        synchronized(this)
        {

        }

分布式锁:

synchronized和ReentratLock只适用于单例服务,并不适用于微服务模式。 synchronized 和 ReentratLock 加锁的作用域只是当前服务。 在当前服务内的多进程下可以保证数据唯一性。但是当在分布式环境下,有多个相同的服务部署在不同服务器时, 使用redis会出现风险。 synchronized不可能锁住好几个服务的数据。 此时需要使用redis自带的set方法来完成锁数据的操作。

setIfAbsent方法提供在分布式环境下对数据的加锁处理。
       /**
         * stringRedisTemplate 提供setIfAbsent方法对指定的内容加锁。
         * 适用于分布式架构
         * 按照唯一键lockKey加锁, 返回boolean类型的加锁结果
         * setIfAbsent表示如果已经存在lockKey的锁,则不会继续加锁,返回false表示加锁失败
         * 如果不存在lockKey的锁,则对value进行加锁,然后执行业务代码
         */
        String lockKey = UUID.randomUUID().toString()+ "serverName";
        String value = "被加锁的内容";
        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(lockKey , value);
        if(!flag)
        {
            // 加锁失败
        }
        else
        {
            //指定业务代码后,释放锁
            stringRedisTemplate.delete(lockKey);
        }

上述代码可以完成分布式加锁,但存在一个问题。 如果程序执行到业务代码中时,抛出异常了怎么办? 应为解锁代码在业务代码之后,也就是多要在业务代码执行完成后在解锁。 但是如果业务代码指定一半是抛出了异常,那么最后的解锁代码也执行不到。 

为了解决这个问题, 需要对从加锁开始到执行业务代码 进行 try-catch处理。 在finally语句中释放锁。 这样不论业务代码有没有抛出异常,最后都会解锁。

  /**
         * stringRedisTemplate 提供setIfAbsent方法对指定的内容加锁。
         * 适用于分布式架构
         * 按照唯一键lockKey加锁, 返回boolean类型的加锁结果
         * setIfAbsent表示如果已经存在lockKey的锁,则不会继续加锁,返回false表示加锁失败
         * 如果不存在lockKey的锁,则对value进行加锁,然后执行业务代码
         */
        String lockKey = UUID.randomUUID().toString()+ "serverName";
        String value = "被加锁的内容";
        try
        {
            Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(lockKey , value);
            if(!flag)
            {
                // 加锁失败
            }
            else
            {
                //执行业务代码

            }

        }
        catch (Exception e)
        {

        }
        finally {
            stringRedisTemplate.delete(lockKey);
        }
        return ResponseResult.ok(message);
    }

在解决了程序因为抛异常而无法执行到解锁语句的问题后, 还有一个问题没有解决。 那就是: 如果程序执行到业务代码,但是整个宕机了,整个服务挂掉了,可能是谁杀了服务的进行。这时候哪怕是有finally语句,因为进程被杀了,也无法执行到。 但是redis还正常运行。 被加锁的数据因此无法解锁。 这时候该怎么办? 所以,为了因对这种情况, 在对数据加锁时, 需要对数据指定超时时间。 指定超时时间后,即时服务宕机无法执行到解锁语句,在redis中加锁的数据也有一个超时时间,超时后对自动删除。

// 给被加锁数据设置一个超时时间
stringRedisTemplate.expire(lockKey , 10, TimeUnit.SECONDS);


// 要保证加锁和给所一个时间 是一个原子操作
Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(lockKey , value , 10 , TimeUnit.SECONDS);
华大HC32F460串口超时中断+DMA收发实战:从STM32迁移的避坑指南 本文为从STM32迁移至华大HC32F460的开发者提供了串口DMA收发的实战避坑指南。核心在于理解HC32F460以串口接收超时中断替代空闲中断的机制,并调整DMA配置策略:DMA应设置为由串口接收事件持续触发搬运,超时中断仅负责通知和重置DMA,从而实现高效可靠的数据收发。 阅读详情

相关推荐

手把手教你用Python分析OpenFAST仿真结果:pyDatView处理.out文件与数据可视化技巧

本文详细介绍了如何使用Python中的pyDatView工具分析OpenFAST仿真结果,包括数据加载、质量检查、时域与频域分析、多工况对比及自动化报告生成。通过优化技巧和可视化方法,帮助工程师高效处理.out文件,提升风机性能分析的准确性和效率。

weixin_29311017的博客 182

Redis实现分布式锁--单机版

使用单机版redis实现分布式锁

whq789456的博客 431

Fluent新手必看:如何正确解读scaled residuals曲线(附常见问题排查)

本文详细解析了Fluent中scaled residuals曲线的解读方法及常见问题排查技巧。针对continuity残差居高不下、湍流模型收敛困难等典型问题,提供了网格质量检查、边界条件验证和求解策略调整的实用解决方案,帮助CFD新手快速掌握计算收敛性的关键判断标准。

weixin_28698059的博客 373

Redis中的单机锁到分布式锁

Jedis 是 Redis 官方推荐的Java客户端开发包,后来SpringBoot对Redis客户端进行了封装使用了 redisTemplate,springBoot1.x底层使用的还是Jedis,而到了springBoot2.x时,具体实现变成了lettuce。今天我们从Redis的单机锁讲到分布式锁,分析了从Redlock到Lua脚本的演进,最后结合Spring的最佳实践,推荐了Redisson的使用。释放锁时,必须确保只有拥有锁的那个客户端才能释放它,否则可能会误释放别人的锁。

小蒋聊技术 1153

Python脚本自动化芯片设计?PyAether实战教程带你玩转EDA

本文通过PyAether实战教程,详细介绍了如何利用Python脚本实现芯片设计自动化。内容涵盖环境搭建、核心对象模型解析,并重点演示了原理图自动生成、参数化单元创建及设计验证流程集成,帮助EDA工程师从重复性手动操作中解放,显著提升设计效率与一致性。

e4f5g6h的博客 1312

从零开始学版图(二)-----------差分放大电路

从零开始学版图

m0_56112720的博客 8556

redis实战---分布式锁--单机篇

Redis分布式锁是一种基于Redis实现的分布式锁机制,它可以保证在分布式环境中,同一时刻只有一个客户端能够获取到锁,从而避免了多个客户端同时对同一资源进行修改的问题。接下来我将结合一个秒杀的例子讲述如果实现Redis的分布式锁。

郝老三~~~~~~~~~~~~~ 1131

从零开始学习CANoe(三)—— 系统变量的创建和使用

从零开始学习CANoe(三)—— 系统变量的创建和使用

蚂蚁小兵 1万+

Redis分布式锁单机版和集群版(7种)

Redis 分布式锁解决方案7种解决方案,生产场景一次搞定

AI架构师Array的博客 841

Oracle EBS 帐套(Ledger/SOB)如何定义会计主体、如何支撑多准则 / 多报告、组织与帐套的绑定关系、以及项目落地时的设计差异。下面从实现逻辑、核心要素、组织模型、多账簿、科目设计、项

本文对比了Oracle EBS R12与SAP S/4HANA在帐套(Ledger)设计上的核心差异。Oracle采用4C架构(科目/币种/日历/准则),帐套作为独立会计主体,主辅账物理隔离;SAP则以公司代码为主体,通过平行分类账在同一凭证中实现多准则核算。关键差异体现在:Oracle强调边界隔离,适合差异大的集团;SAP注重统一视图,适合实时合并需求。实施时需注意:Oracle避免过度建账套,SAP需统筹科目与维度设计。两者分别体现了"盒子"与"滤镜"的设计哲学。

金牌架构师 415

关于如何在matlab中导入并翻译Hypemesh导出的大型刚度矩阵txt文本

如何将它翻译成matlab可以使用的矩阵变量,并参与运算。 由于这个大型刚度矩阵125万x125万≈1e12。matlab甚至其他计算软件无法保存这个大的一个矩阵文件。而这个刚度矩阵作为稀疏矩阵其中非零元素的数目只有有500多万。采用sparse稀疏矩阵技术是可以保存。 这里简单介绍一下这个Hypemesh导出的大型刚度矩阵txt文本。如图DMIG开头的标识符是换行符,后面两列是表示这条非零元素在刚度矩阵中列数的信息。我们已经将左边字母和符号等批量删除,得到了右边textread函数可以...

wenyusuran的专栏 1795

redis分布式锁 以及单机锁 代码套用

类似于单机jvm锁机制 // 获取锁 Lock lock = new ReentrantLock(); if(lock ==null){ throw new Exception("-----------"); } try{ }catch(Exception e){ }finally{ lock.unlock(); } @Resource private Redisson redisson; //分布式锁套用代码 RLock redissonlLock = Redisson.getL.

weixin_41500775的博客 298

【Bug已解决】This model‘s maximum context length is X tokens. However, you requested Y tokens 解决方案

summary_prompt = "请将以下对话历史压缩成一段简洁摘要,保留关键决策和结论:\n" + format_messages(old_part)return [{"role": "system", "content": f"此前对话摘要:{summary}"}] + recent_part这种方式能在大幅降低 token 消耗的同时,尽量保留任务推进所需的关键上下文,是目前业内做长会话 Agent 最常见的处理方式之一。方案适用场景推荐指数滑动窗口裁剪短任务,对早期历史依赖不强⭐⭐⭐。

一键难忘的博客 1万+

从单机锁到 Redis 分布式锁

Redisson 内置后台异步定时任务,仅在(无参 lock ())时激活,业务线程持有锁期间,定时刷新锁 TTL,避免业务未执行完成锁自动释放。

2401_87174643的博客 2398

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

redis 单机锁 和 分布式锁

单机锁 代码偷自:https://www.cnblogs.com/iforever/p/5796902.html <?php require "vendor/autoload.php"; $client = new Predis\Client([ 'scheme' => 'tcp', 'host' =&

harryhare的专栏 799

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

redis 设置timeout_【redis】redis 单机锁 和 分布式锁

一、单机锁代码示例: 代码出自:redis并发问题 - 奔跑的Man - 博客园<?php require "vendor/autoload.php"; $client = new PredisClient([ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, ]); clas...

weixin_39610085的博客 253

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

redis setnx 实现分布式锁和单机锁

对应给定的keys到他们相应的values上。只要有一个key已经存在,MSETNX一个操作都不会执行。由于这种特性,MSETNX可以实现要么所有的操作都成功,要么一个都不执行,这样可以用来设置不同的key,来表示一个唯一的对象的不同字段。 在 Redis 里,所谓 SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果,不

pzqingchong的专栏 1万+

详细讲解分布式锁,Redis分布式锁和单机版锁(进阶提升),JVM单机锁,Redis面试必备

我们可以使用多种方式来实现强一致性,比如分布式事务,一致性算法,分布式锁等等。这篇文章将围绕这个话题展开。首先,我们会先探究它的,然后结合实际应用对目前较为常见的进行详细的分析。大家可以先思考三个问题。

qq_50896685的博客 1649

SpringBoot 分布式锁实战:从单机锁到Redis分布式锁全覆盖,解决超卖、重复下单、幂等并发问题

做电商、支付、库存扣减、优惠券核销、订单创建、接口幂等场景,并发安全是底线。很多新手本地测试加个或者 ReentrantLock,本地压测没问题,一上生产集群部署,立马出现:✅ 库存莫名超卖、✅ 同一用户重复下单、✅ 重复扣款对账不平、✅ 定时任务集群重复执行核心原因就一句话:单机锁只锁当前JVM实例,集群多台服务互不感知,锁直接失效。

KmSH8umpK的博客 631

从单机锁到分布式锁:Redis实现方案对比

单机锁用于单进程或多线程环境,确保同一时间只有一个线程访问共享资源。互斥锁(Mutex):通过操作系统或编程语言提供(如Python的信号量(Semaphore):控制并发访问数量。with lock: # 获取锁shared_resource += 1 # 安全访问共享资源# 释放锁自动完成仅适用于单节点,无法在分布式集群中工作。节点故障时,锁状态无法恢复,可能导致死锁。在分布式系统中,节点间网络延迟和故障风险增加,因此需要分布式锁来保证全局一致性。

kkshdgxcjsd的博客 441

实战高并发秒杀:从单机锁失效到 Redis 分布式锁的深度进化

本文深入复盘了在“一人一单”高并发秒杀场景下,互斥机制从单机 synchronized 锁升级为 Redis 分布式锁的完整演进过程。文章首先剖析了 Nginx 集群部署导致本地锁失效的根本原因,随后在手写 Redis 锁的实战中,详细复现了高并发下“误删他人锁”的严重 Bug。

qq_52041827的博客 1028

手写Redis分布式锁

手写Redis分布式锁

xiaguxiagu的博客 1801

Redis+IDEA极速了解和实现单机锁和分布式锁

只适用于单机环境下(单个JVM),多个客户端访问同一个服务器。

m0_62314761的博客 893

Redisson 实现分布式锁

单机锁:用于一台服务器的同步执行。分布式锁:用于多台服务器之间的同步执行。有限资源的情况下,控制同一时间(段)只有某些线程(用户 / 服务器)能访问到资源。Java 实现锁:synchronized 关键字、并发包的类。Java synchronized 实现锁存在问题:只对单个 JVM 有效。分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。

weixin_69912448的博客 1635

Redis学习:Redis可重入分布式锁、Redlock算法和底层源码分析

Redis学习:自研实现可重入Redis分布式锁、Redlock算法和底层源码分析

LiuYQi的博客 1513

Java锁这样用,从单机到分布式一步到位

String errorMessage() default "获取锁失败,请稍后重试";只能在单个JVM内使用基于Redis实现支持跨JVM协调使用简单,一个注解搞定减少重复代码,降低出错概率单机应用:使用synchronized或ReentrantLock分布式应用:使用Redisson分布式锁追求简洁:使用注解式分布式锁掌握这套锁的升级方案,让你的应用在任何环境下都能保证数据安全!大毛啊Java锁这样用,从单机到分布式一步到位 - 大毛啊 - 博客园JNPF快速开发平台。

sdgfafg_25的博客 1046
上一篇: jenkins 学习
下一篇: XXL-JOB 任务
libingbojava
博客等级 码龄9年 64粉丝 111原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值