【Redis】Redisson入门以及Redisson可重入锁的lua脚本实现

news2024/11/27 18:52:03

目录

一、Redisson介绍

二、Redisson的入门

1、引入依赖

2、配置客户端

3、使用锁

三、Redisson可重入锁的原理

1、原理

2、实现

3、lua脚本保证原子性

1.获取锁

2.释放锁


一、Redisson介绍

在之前的文章里我们通过redis中的setn实现了一个简单的分布式锁以及解决了误删、原子性等问题,但他依旧存在不足。我们在项目中一般使用比较成熟的分布式锁,Redisson是一个在redis基础上实现的Java驻内存数据网格,他不仅提供了一系列分布式的常用Java对象,他还提供了许多分布式服务,就比如分布式锁,Redisson中的分布式锁则不存在上述的问题,我们在项目中完全可使用

二、Redisson的入门

1、引入依赖

首先我们需要在项目的pom文件中引入对应的依赖

<dependency>
			<groupId>org.redisson</groupId>
			<artifactId>redisson</artifactId>
			<version>3.13.6</version>
		</dependency>

2、配置客户端

其次我们需要创建一个配置类来进行客户端的配置

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedisConfig {
    
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://IP:6379").setPassword("密码");
        return Reisson.create(config);
    }
}

3、使用锁

其次我们就可以在项目中进行使用了

package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.TimeUnit;

public class Use {
    @Autowired
    private RedissonClient redis;
    
    public void test() {
        // 获取锁
        RLock lock = redis.getLock("name");
        // 尝试获取锁:  参数1 最大等待时间   参数2 锁自动释放时间 参数3 时间单位
        boolean isLock = lock.tryLock(1,111, TimeUnit.SECONDS);
        if (!isLock) {
            try {
                // 业务代码
            } finally {
                lock.unlock();
            }
        }
    }
}

三、Redisson可重入锁的原理

1、原理

线程1在方法1中获取到了锁,此时在redis锁中会记录持有这把锁的线程,然后执行方法1,在方法1中调用了方法2,进入方法2后发现方法2也需要获取锁,此时线程在获取锁时发现这个锁已经被获取了,此时就进行判断,如果发现是自己获取了这把锁,这直接进入执行业务,但是方法2执行完释放锁时,此时锁并不是真正的释放还需要去执行完方法1所剩的业务才可以释放,为了解决提前释放锁的问题,在实现时会维护一个计数器,当线程获取到锁后计算器会进行加1,当再次进入时计数器再加1变为2,此时方法2执行完释放锁计数器-1,此时计数器不为0则重置锁的过期时间不删除,当计数器=0时说明锁真正释放,删除锁

2、实现

在redis中实现可重入锁时需要维护一个计数器字段,但是传统的string类型是没有办法做到的,此时我们可以使用redis中的hash类型

3、lua脚本保证原子性

1.获取锁

在获取锁时我们先要判断锁是否存在,不存在则插入数据直接获取锁,如果存在则需要判断这把锁是不是自己持有,如果是则需要使得计数器+1,如果我们在Java中提供代码去一条一条的执行时,这些操作并不是原子性的,会带来线程安全问题(前面有提到)所以我们必须保证这些操作是原子性的,我们可以通过lua脚本来实现

【Redis】实现及优化分布式锁:实现、解决误删锁问题以及lua脚本确保redis操作原子性_1373i的博客-CSDN博客icon-default.png?t=N3I4https://blog.csdn.net/qq_61903414/article/details/130631441?spm=1001.2014.3001.5501

local key = KEYS[1] -- 锁的key
local threadId = ARGV[1] -- 线程标识
local time = ARGV[2] -- 锁的ttl

-- 判断锁是否存在
if (redis.call('exists',key) == 0) then
    -- 不存在,获取锁
    redis.call('hset',key,1);
    -- 设置ttl
    redis.call('expire',key,time);
    return 1;
end;

-- 锁存在判断是否属于自己
if (redis.call('hexists',key,threadId) == 1) then
    -- 属于自己计数器自增
    redis.call('hincrby',key,threadId,'1');
    -- 重置ttl
    redis.call('expire',key,time);
    return 1;
end;
return 0;  -- 此时说明锁不是自己的  获取失败

2.释放锁

释放锁时,我们先要判断锁是不是自己的,如果是自己的则让计数器-1,然后再判断计数器是否为0,如果为0则删除锁,这些操作也需要保证原子性

local key = KEYS[1] -- 锁的key
local threadId = ARGV[1] -- 线程标识
local time = ARGV[2] -- 锁的ttl

-- 判断锁是否是自己的
if (redis.call('hexists',key) == 0) then
    -- 不是自己的直接返回
    return nil;
end;

-- 说明锁是自己的计数器-1
local count = redis.call('hincrby',key,threadId,-1);

-- 判断计数器是否为0
if (count > 0) then
    -- 说明不能释放锁,重置有效期
    redis.call('expire',key,time);
    return nil;
else -- 说明可以释放
    redis.call('del',key);  -- 删除
end

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

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

相关文章

远程协助软件推荐,有哪些远程协助工具?

Win10、11自带远程协助工具-快速助手 Win10、11的快速助手使用非常简单。只要在左下角的搜索框搜索一下就可以找到了。 我们都知道&#xff0c;Windows带有远程桌面RDP功能&#xff0c;而快速助手是通过Windows的远程连接机制实现的。所以在使用前&#xff0c;被控端需要开启系…

谈薪谈蹦了,阿里HR说我不配21K....

好家伙&#xff0c;这奇葩事可真是多&#xff0c;前两天和粉丝聊天&#xff0c;他说前段时间面试阿里的测开岗&#xff0c;最后和面试官干起来了。 我问他为什么&#xff0c;他说没啥&#xff0c;就觉得面试官太装了&#xff0c;我说要24K&#xff0c;他说太高了&#xff0c;说…

Kyligence Zen 产品体验——超好用指标平台一站式体验教程

目录 背景介绍Kyligence Zen介绍上手指南数据概览可视化图表 自定义数据新建表新建视图 指标体验目标仪表盘集成优点个人建议体验总结每文一语 背景介绍 在数字化建设初期&#xff0c;许多企业主要采用基于商业智能&#xff08;BI&#xff09;报表的方式来处理数据&#xff0c…

杨红春没有“雷军”,良品铺子“高端”之路焦虑

文 | 螳螂观察 作者 | 图霖 如果休闲零食赛道要评一个六边形战士&#xff0c;良品铺子绝对是个不错的候选人。 尽管搭乘电商的风头起势&#xff0c;但得益于早期线下开店的经验&#xff0c;成功实现了两条腿走路。最新年报显示&#xff0c;其2022年线上收入占比为50.42%&…

《统计学习方法》——隐马尔可夫模型(上)

引言 隐马尔可夫模型(Hidden Markov Model,HMM)是描述隐藏的马尔可夫链随机生成观测数据过程的模型。 前置知识 马尔可夫链 马尔可夫链(Markov chain)又称离散时间马尔可夫链&#xff0c;使用 t t t来表示时刻&#xff0c;用 X t X_t Xt​来表示在时刻 t t t链的状态&#…

( 位运算 ) 338. 比特位计数 ——【Leetcode每日一题】

❓338. 比特位计数 难度&#xff1a;简单 给你一个整数 n &#xff0c;对于 0 < i < n 中的每个 i &#xff0c;计算其二进制表示中 1 的个数 &#xff0c;返回一个长度为 n 1 的数组 ans 作为答案。 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;[0,1,…

JavaScript变量声明

声明变量三个var let和const 1.首先var先排除&#xff0c;老派写法&#xff0c;问题很多&#xff0c;可以淘汰掉… 2.const优先&#xff0c;尽量使用const,原因&#xff1a; &#xff08;1&#xff09;const语义化更好 &#xff08;2&#xff09;很多变量声明的时候就知道它不会…

中本聪思想精髓难以领悟?Web3实际上还在“幻想”之中?

Web3概念是不错&#xff0c;有人说它是下一代互联网&#xff0c;有人说它是NFT和元宇宙等未来应用的基础设施。然而理论炒得火热&#xff0c;但却仍不见像ChatGPT一样能引爆市场的杀手级应用出现。 原因在于&#xff0c;当前的Web3概念是对中本聪思想的不断概括和提炼&#xff…

21 KVM管理虚拟机-在线修改虚拟机配置

文章目录 21 KVM管理虚拟机-在线修改虚拟机配置21.1 概述21.2 操作步骤 21 KVM管理虚拟机-在线修改虚拟机配置 21.1 概述 虚拟机创建之后用户可以修改虚拟机的配置信息&#xff0c;称为在线修改虚拟机配置。在线修改配置以后&#xff0c;新的虚拟机配置文件会被持久化&#x…

高通410 随身WIFI刷入Debian系统(玩法合集)

引言 刚接触到这个项目是在b站上&#xff0c;刷到一位UP主的视频&#xff1a;https://b23.tv/xAFWiTF 其实现了在搭载高通410芯片的随身WIFI烧录linux系统&#xff0c;并在上面部署了chatGPT-Next网站服务。 本人参考的教程链接和其教程所有工具&#xff1a;https://pan.bai…

域名历史查询-免费批量域名历史快照注册时间查询软件

域名历史查询 域名历史查询是指通过查询工具&#xff0c;查询一个域名在过去的历史记录&#xff0c;包括注册时间、过期时间、更改记录、备案信息、WHOIS信息、IP记录、Alexa排名、流量统计等方面。通过查询域名的历史信息&#xff0c;研究者可以了解域名过去的状态&#xff0…

Map与Set中的两大实现类✌

map与set中的两大实现类 map和setSet的两种常用形态Map的两种常用形态实战&#x1f4aa; map和set 哈希表&#xff08;hashMap&#xff09;和 集合 (Set)是数据结构中比较常用的一部分&#xff0c;他们的特性通常可以解决很多问题&#xff0c;这两个数据结构是同根生&#xff…

Python开发之实现SG滤波

Python开发之实现SG滤波 1 SG滤波2 借助Python中的scipy.signal库实现SG滤波3 手动代码实现SG滤波 前言&#xff1a;主要介绍SG滤波的Python实现&#xff0c;顺带介绍SG滤波的实现原理。 1 SG滤波 Savitzky-Golay滤波器&#xff08;通常简称为S-G滤波器&#xff09;最初由Savi…

一百一十六、Zeppelin——Zeppelin0.9.0连接ClickHouse21.9.5.16(亲测有效,附步骤截图)

版本&#xff1a;Zeppelin0.9.0 ClickHouse21.9.5.16 1.目标&#xff1a;Zeppelin连上clickhouse&#xff0c;可以把clickhouse中的数据做可视化展示 2.参考文件&#xff1a;如何基于zeppelin JDBC Interpreter进行jdbc数据源的可视化交互分析 http://t.csdn.cn/DGH…

数智融合 | 美格智能助力AIGC产业迈向新未来

5月11日&#xff0c;在2023 “高通&美格智能物联网技术开放日”深圳站活动上&#xff0c;美格智能副总经理金海斌以《数智引领 融合创新》为题分享了5GAIoT技术赋能的价值展望。 ▲美格智能副总经理 金海斌 ▌算力&#xff1a;数字经济时代的“石油” 今年&#xff0c;由C…

Spring Boot 拦截器

Spring Boot 拦截器介绍 Spring Boot 拦截器是 AOP 的一种实现&#xff0c;专门拦截对控制层的请求&#xff0c;主要应用于判断用户权限&#xff0c;拦截webSocket请求。SpringBoot中的拦截器实现和spring mvc 中是一样的&#xff0c;它的大致流程是&#xff0c;先自己定义一个…

软件测试注意面试官的常规“套路”

一、自我介绍 这里就不过多阐述了&#xff0c;相信很多小伙伴都有。 二、灵活问题 1、大概说说之前公司的测试流程。 2、测试报告有哪些内容? 3、如何保证用例的覆盖度? 4、什么是测试用例,什么是测试脚本?两者的关系&#xff1f; 5、Bug的级别&#xff0c;按照什么划…

使用Simulink中的MATLAB Function模块存在的bug

为什么simulink中的MATLAB Function 模块需要按Ctrl+C才能中断程序??? 否则就会像这样一直是正在运行!!需要按Ctrl+C才能中断循环!!神奇的是每次需要按Ctrl+C才可运行simulink程序?? 再次打开Simulink中MATLAB function模块会出现以下bug: function [qr, qr_a, qr…

【Android Jetpack】新一代导航管理——Navigation

前言 不知道小伙伴们是否注意到&#xff0c;用AS创建一个默认的新项目后&#xff0c;MainActivity已经有了很大的不同&#xff0c;最大的区别就是新增加了两个Fragment&#xff0c;同时我们注意到这两个Fragment之间跳转的时候并没有使用之前FragmentTransaction这种形式&…

Nginx基本使用以及部署前端项目

前言 最近学习了一下Nginx&#xff0c;整理了一个博客&#xff0c;主要参考的是狂神说的b站视频教程&#xff0c;文章链接如下&#xff1a;狂神说Nginx快速入门 一、下载、启动Nginx 1.下载Nginx 到Nginx官方选择自己电脑适用的稳定版本下载&#xff0c;我下载的的windows版…