redis分布式锁介绍及代码示例

Redis 分布式锁是一种利用 Redis 实现的分布式系统中的锁机制,用于在分布式环境下控制多个客户端对共享资源的访问。它通过 Redis 的原子性操作来确保在分布式系统中的不同节点上,同一时刻只有一个客户端能够获取到锁,从而保证了对共享资源的互斥访问。

分布式锁通常在以下情况下使用:

共享资源访问控制: 当多个客户端需要访问共享资源时,为了避免并发访问导致的数据不一致或竞态条件问题,可以使用分布式锁来控制对资源的访问。防止重复执行: 在分布式系统中,某些操作可能需要保证只能被执行一次,例如定时任务的执行、数据同步等,可以使用分布式锁来确保操作只会被执行一次。避免缓存击穿: 当缓存中的数据过期时,可能会出现大量并发请求同时访问数据库的情况,为了避免这种情况,可以使用分布式锁来保证只有一个请求可以去数据库中重新加载数据,其他请求等待结果返回。

示例代码1:

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;import java.util.concurrent.TimeUnit;public class RedissonDistributedLock {private static final String LOCK_KEY = "mylock";private static final long LOCK_EXPIRE_TIME = 30; // 锁的过期时间,单位秒private RedisTemplate<String, String> redisTemplate;private RedissonClient redissonClient;public RedissonDistributedLock(RedisTemplate<String, String> redisTemplate, RedissonClient redissonClient) {this.redisTemplate = redisTemplate;this.redissonClient = redissonClient;}public boolean acquireLock() {RLock lock = redissonClient.getLock(LOCK_KEY);try {return lock.tryLock(LOCK_EXPIRE_TIME, TimeUnit.SECONDS);} catch (InterruptedException e) {Thread.currentThread().interrupt();return false;}}public void releaseLock() {RLock lock = redissonClient.getLock(LOCK_KEY);lock.unlock();}public static void main(String[] args) {// 初始化 RedisTemplate 和 RedissonClientRedisTemplate<String, String> redisTemplate = // 初始化 RedisTemplateRedissonClient redissonClient = Redisson.create(); // 初始化 RedissonClientRedissonDistributedLock lock = new RedissonDistributedLock(redisTemplate, redissonClient);try {if (lock.acquireLock()) {// 成功获取锁后执行业务逻辑System.out.println("成功获取到锁,执行业务逻辑...");Thread.sleep(5000); // 模拟业务逻辑执行时间} else {// 获取锁失败,处理逻辑System.out.println("获取锁失败,处理逻辑...");}} catch (InterruptedException e) {e.printStackTrace();} finally {// 释放锁lock.releaseLock();}}
}

在这个示例中,我们创建了一个 RedissonDistributedLock 类,它接收一个 RedisTemplate 和 RedissonClient 作为参数,并提供了 acquireLock 和 releaseLock 方法来获取和释放锁。在 main 方法中,我们初始化了 RedisTemplate 和 RedissonClient,并使用 RedissonDistributedLock 来实现分布式锁。


示例代码2:

import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.util.Collections;public class RedisDistributedLock {private static final String LOCK_KEY = "mylock";private static final String LOCK_VALUE = "locked";private static final long LOCK_EXPIRE_TIME = 30000; // 锁的过期时间,单位毫秒private RedisTemplate<String, String> redisTemplate;public RedisDistributedLock(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;// 设置 RedisTemplate 的序列化器,保证 key 和 value 都以字符串的形式存储redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());}public boolean acquireLock() {// 使用 Lua 脚本确保原子性操作String script = "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then "+ "redis.call('pexpire', KEYS[1], ARGV[2]) return true else return false end";DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(script, Boolean.class);Boolean result = redisTemplate.execute(redisScript, Collections.singletonList(LOCK_KEY), LOCK_VALUE, String.valueOf(LOCK_EXPIRE_TIME));return result != null && result;}public void releaseLock() {// 释放锁redisTemplate.delete(LOCK_KEY);}public static void main(String[] args) {// 初始化 RedisTemplateRedisConnectionFactory connectionFactory = // 设置 Redis 连接工厂RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.afterPropertiesSet();RedisDistributedLock lock = new RedisDistributedLock(redisTemplate);try {if (lock.acquireLock()) {// 成功获取锁后执行业务逻辑System.out.println("成功获取到锁,执行业务逻辑...");Thread.sleep(5000); // 模拟业务逻辑执行时间} else {// 获取锁失败,处理逻辑System.out.println("获取锁失败,处理逻辑...");}} catch (InterruptedException e) {e.printStackTrace();} finally {// 释放锁lock.releaseLock();}}
}

这段代码使用了 RedisTemplate 来与 Redis 进行交互,通过执行 Lua 脚本来确保获取锁的原子性操作。在 acquireLock 方法中,通过执行 Lua 脚本来设置锁,并设置了锁的过期时间,从而避免了因为程序异常而导致锁永远不释放的情况。在业务逻辑执行完成后,调用 releaseLock 方法来释放锁。

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

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

相关文章

自动化测试selenium

目录 什么是自动化测试 什么是selenium selenium工作原理 selenium环境搭建 1.查看chrome浏览器版本 2.下载chrome浏览器驱动 3.配置系统环境变量PATH 4.验证环境是否搭建成功 selenium相关API 1.定位元素 CSS选择器定位 xpath定位元素 标签定位元素 2.操作测试对…

2024年华为OD机试真题-孙悟空吃蟠桃-Python-OD统一考试(C卷)

题目描述: 孙悟空爱吃蟠桃,有一天趁着蟠桃园守卫不在来偷吃。已知蟠桃园有N颗桃树,每颗树上都有桃子,守卫将在H小时后回来。 孙悟空可以决定他吃蟠桃的速度K(个/小时),每个小时选一颗桃树,并从树上吃掉K个,如果树上的桃子少于K个,则全部吃掉,并且这一小时剩余的时间…

novnc本地文件读取和写入权限

在使用NoVNC&#xff08;一种基于Web的VNC客户端&#xff09;时&#xff0c;出于安全考虑&#xff0c;通常不允许直接从客户端访问或修改服务器上的文件系统。如果你需要在NoVNC中实现文件的读写&#xff0c;你可能需要使用一些特殊的配置或者服务器端的支持。 例如&#xff0…

浏览器工作原理与实践--渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题

在专栏开篇词中&#xff0c;我们提到过浏览器的三大进化路线&#xff1a; 第一个是应用程序Web化&#xff1b; 第二个是Web应用移动化&#xff1b; 第三个是Web操作系统化&#xff1b; 其中&#xff0c;第二个Web应用移动化是Google梦寐以求而又一直在发力的一件事&#xf…

【免费SSL】免费一年的SSL证书

一、SSL证书行业政策 目前市面上绝大多数的免费SSL证书有效期都在3个月左右&#xff0c;而不是一年。例如&#xff0c;腾讯云在2024年4月后不再提供有效期为一年的免费证书&#xff0c;改为提供有效期为3个月的免费证书。同样&#xff0c;阿里云在2023年11月后也不再提供有效期…

javaScript常见对象方法总结

1&#xff0c;object.assign() 用于合并对象的属性。它可以将一个或多个源对象的属性复制到目标对象中&#xff0c;实现属性的合并。 语法 Object.assign(target, ...sources); 1,target&#xff1a;目标对象&#xff0c;将属性复制到该对象中。 2,sources&#xff1a;一个…

51单片机学习笔记16 小型直流电机和五线四相电机控制

51单片机学习笔记16 小型直流电机和五线四相电机控制 一、电机分类二、小型直流电机控制1. 简介2. 驱动芯片ULN2003D3. 代码实现dc_motor_utils.cmain.c 三、五线四相步进电机控制1. 步进电机工作原理2. 构造3. 极性区分4. 驱动方式5. 28BYJ-48步进电机&#xff08;1&#xff0…

3D可视化技术亮相高铁站,引领智慧出行新潮流

在科技飞速发展的今天&#xff0c;我们的生活正经历着前所未有的变革。高铁站作为现代交通的重要枢纽&#xff0c;也在不断地创新和进步。 3D可视化技术通过三维立体的方式&#xff0c;将高铁站内部和外部的结构、设施、流线等以更加直观、生动的形式呈现出来。乘客们只需通过手…

幸运的彩票

题目描述 彩票的号码有 6 位数字&#xff0c;若一张彩票的前 3 位上的数之和等于后 3 位上的数之和&#xff0c;则称这张彩票是幸运的。本题就请你判断给定的彩票是不是幸运的。 输入格式 输入在第一行中给出一个正整数 N&#xff08;≤ 100&#xff09;。随后 N 行&#xff0…

Docker容器嵌入式开发:MySQL表的外键约束及其解决方法

本文内容涵盖了使用MySQL创建数据库和表、添加数据、处理字符集错误、解决外键约束问题以及使用SQL查询数据的过程。通过创建表、插入数据和调整字符集等操作&#xff0c;成功解决了数据库表中的字符集问题&#xff0c;并使用INSERT语句向各个表中添加了示例数据。同时&#xf…

MySQL - MySQL的RR隔离级别是如何基于ReadView机制实现的?

RR级别下,这个事务读取一条数据,无论读多少次,都是一个值,别的事务修改数据之后,哪怕提交了,你也是看不到人家修改的值的,这就避免了不可重复读的问题。 同时如果别的事务插入了一些新的数据,你也是读不到的,这样就可以避免幻读问题。这到底是如何实现的呢? 首先我…

《深入Linux内核架构》第1章 简洁和概述

目录 1.1 内核的任务 1.2 实现策略 1.3 内核的组成部分 ​1.3.1 进程、进程切换、调度 1.3.2 UNIX 进程 1.3.3 地址空间和特权级别 1.3.4 页表 1.3.5 物理内存的分配 1.3.6 计时 1.3.7 系统调用 1.3.8 设备驱动程序 1.3.9 网络 1.3.10 文件系统 1.3.11 模块和热插…

LangChain - Output Parsers

文章目录 一、输出解析器 (Output Parsers)快速入门 二、列表解析器三、datetime 日期时间解析器四、枚举解析器五、自动修复解析器六、Pydantic&#xff08;JSON&#xff09;解析器七、重试解析器八、结构化输出解析器 structured 转载改编自&#xff1a; https://python.lang…

AIGC实战——StyleGAN(Style-Based Generative Adversarial Network)

AIGC实战——StyleGAN 0. 前言1. StyleGAN1.1 映射网络1.2 合成网络1.3 自适应实例归一化层1.4 风格混合1.5 随机变化 2. StyleGAN 生成样本3. StyleGAN23.1 权重调制与解调3.2 路径长度正则化3.3 非渐进式增长 4. StyleGAN2 生成样本小结系列链接 0. 前言 StyleGAN (Style-Ba…

【LeetCode热题100】【二叉树】对称二叉树

题目链接&#xff1a;101. 对称二叉树 - 力扣&#xff08;LeetCode&#xff09; 递归解决&#xff0c;如果都空那么相等&#xff0c;否则有一个为空那么不相等&#xff0c;剩下就是都不为空&#xff0c;判断元素是否相等&#xff0c;接着递归判断左边的左子树是否等于右边的右…

安卓的认证测试

1 CTS CTS 是 Android 兼容性测试套件&#xff0c;用于验证设备是否符合 Android 平台的兼容性标准。它包含一系列测试用例&#xff0c;涵盖了设备的各个方面&#xff0c;如硬件功能、软件功能、API 的正确实现等。通过 CTS 测试&#xff0c;设备厂商可以确保其设备符合 Andro…

软件工程、微服务架构风格的概念以及实际应用

微服务架构风格的概念 微服务架构是一种将一个应用程序作为一套小的服务的开发风格&#xff0c;每个服务运行在其自己的进程中&#xff0c;并通常围绕着业务能力组织。这些服务可以通过轻量级的通信机制&#xff08;通常是HTTP RESTful API&#xff09;相互独立部署、扩展和维…

Accuracy准确率,Precision精确率,Recall召回率,F1 score

真正例和真反例是被正确预测的数据&#xff0c;假正例和假反例是被错误预测的数据。然后我们需要理解这四个值的具体含义&#xff1a; TP&#xff08;True Positive&#xff09;&#xff1a;被正确预测的正例。即该数据的真实值为正例&#xff0c;预测值也为正例的情况&#xf…

python-pytorch使用日志0.5.007

python-pytorch使用日志 1. optimizer.zero_grad()和model.zero_grad()的区别2. cbow和skip-gram的训练数据格式3. 获取cbow和skip-gram训练后的中文词向量4. 获取到词向量后可以做什么5. 余弦相似度结果的解释 1. optimizer.zero_grad()和model.zero_grad()的区别 都是清空模…

学习笔记:解决拖延

1 解决拖延&#xff0c;减轻压力的关键心态和方法 1.1 要点梳理 拖延是因为自己一直在逃避&#xff0c;重点是要有效突破逃避圈&#xff0c;进入学习圈&#xff0c;扩展成长圈。 毒蛇曲线&#xff08;见思维导图&#xff09;中越是临近截止期限&#xff0c;拖延的焦虑越上升…