redis分布式锁(看门枸机制)

news/2024/9/21 12:11:02 标签: redis, 分布式, 数据库

分布式锁确保在同一时间只有一个节点能获得对共享资源的独占访问权限,从而解决并发访问问题。

Redisson锁(简称看门狗)

它可以实现锁的延长,确保某个线程执行完才能让其他线程进行抢锁操作

引入看门狗机制后

如何使用?

1、引入依赖包

<!--Redisson依赖-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.31.0</version>
</dependency>

2、配置类Config

@Configuration //标明是配置类
public class RedissonConfiguration {
    /*注入到IOC容器中*/
    @Bean
    public RedissonClient redissonClient(){
        //1.创建配置对象
        Config config = new Config();
        // 集群模式
        //config.useClusterServers().addNodeAddress("集群ip1", "集群id2");
        //2.根据config创建出RedissonClient实例
          config.useSingleServer()
                .setAddress("redis://192.168.21.131:6379");
​
        //返回 RedissonClient实例
        return Redisson.create(config);
    }
}

3、编写Controller类

@RestController
@Slf4j
@RequestMapping("/api")
public class LockController {
    @Autowired
    private RedissonClient redissonClient;
​
    @PutMapping("/watch-dog")
    public String redissonLock() {
        RLock lock = redissonClient.getLock("anyLock");
            try {
                //尝试获取锁,tryLock参数分别是:获取锁的最大等待时间(期间重试) ,锁自动释放时间,时间单位
​
                //锁的获取时间(重试获得锁)为5秒,超过时间线程未结束会延长锁的获取时间,其他线程无法获得锁
                //boolean isLocked = lock.tryLock(5,10, TimeUnit.SECONDS);
                //不指定锁超时时间,锁会无限续期,直到获得锁的业务逻辑失败
                boolean isLocked = lock.tryLock(5, TimeUnit.SECONDS);
​
                if (isLocked) {
                    log.info("获取锁成功"+Thread.currentThread().getName()+":开始睡觉");
                        Thread.sleep(5*1000);
                    log.info("获取锁成功"+Thread.currentThread().getName()+":睡5秒,");
​
                    // 业务逻辑
                    Thread.sleep(10*1000);
                log.info("获取锁成功"+Thread.currentThread().getName()+":睡眠10秒,超过请求获取锁的时间");
                } else {
                    log.info("锁未释放{}获取锁失败",Thread.currentThread().getName());
                    return "无法获取锁";
                }
​
            } catch (InterruptedException e) {
                e.printStackTrace();
                return "线程被中断";
            } finally {
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
​
        return Thread.currentThread().getName();
    }
}
​
​

4、代码效果

避雷点

关于finallly释放锁时的踩雷点

直接lock.unlock会导致Redisson抛出异常,这个异常的原因是因为,当多个请求进来时,由于一个线程在占用着锁,其他线程无法获得锁,他就会走到finally中,去释放锁,但是由于它本身不带锁,就会触发异常。

解决办法

在释放之前添加if判断

finally{
    if(lock.isHeldByCurrenThread()){
        lock.unlock();  
    }
}
lock.isHeldByCurrenThread(),用于判断当前锁是否是当`前线程持有的,如果是就释放锁,不是就不让它释放,可以避免线程抛出异常。


http://www.niftyadmin.cn/n/5668760.html

相关文章

985和211有什么区别?哪个更好!

985和211是中国高等教育领域的两个重要工程&#xff0c;它们在多个方面存在明显的区别。以下是它们之间的主要区别&#xff1a; 一、提出时间与背景 211工程&#xff1a;该工程于1995年11月提出&#xff0c;旨在面向21世纪&#xff0c;重点建设100所左右的高等学府和一批重点…

Ubuntu24.04中安装Electron

1. 安装Nodejs 使用代理服务从github下载并执行Nodejs安装脚本(假设代理服务器为192.168.2.150:10792) curl -x 192.168.2.150:10792 -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash #注意&#xff0c;Nodejs官网的安装命令少了下面这一行: …

物联网关组态应用案例

产品简介 拓扑未来物联网关是高集成度的物联网采集及通信装置&#xff0c;支持通过RS485串口以太网口进行数据采集&#xff0c;支持数据缓存、协议解析、边缘计算&#xff0c;Ethernet/4G/WIFI数据传输和接入云端平台。支持采集PLC、传感器、仪器仪表和各种控制器&#xff0c;…

用智能码二维码zhinengma.cn做产品说明书

智能码与二维码产品说明书 一、引言 随着科技的快速发展&#xff0c;智能码和二维码已成为我们日常生活中不可或缺的一部分。它们不仅简化了信息的传递过程&#xff0c;还提高了数据的安全性和可追溯性。本说明书将详细介绍如何使用智能码和二维码作为产品说明书&#xff0c;…

vue-使用refs取值,打印出来是个数组??

背景&#xff1a; 经常使用$refs去获取组件实例&#xff0c;一般都是拿到实例对象&#xff0c;这次去取值的时候发现&#xff0c;拿到的竟然是个数组。 原因&#xff1a; 这是vue的特性,自动把v-for里面的ref展开成数组的形式&#xff0c;哪怕你的ref名字是唯一的&#xff01…

后量子密码的研究与实践

一、引言 随着科技的日新月异,信息系统已经深深融入了大家生活的每一角落。然而,科技进步的另一面,信息安全问题愈发引人关注。尤其是在金融行业,数据安全如同生命线,丝毫不得马虎。密码学技术作为确保数据安全的基石,对机密性、完整性、可认证性及不可否认性提供坚实屏…

AIGC生图基础知识

一、引言 AIGC&#xff0c;即AI-Generated Content&#xff0c;是一种利用大型预训练模型如生成对抗网络&#xff08;GAN&#xff09;、扩散网络&#xff08;Diffusion&#xff09;和语言大模型&#xff08;Transformer&#xff09;等人工智能技术&#xff0c;通过对大量数据进…

Conda安装和使用(ubuntu)

以下是关于如何使用 Conda 的详细指南。这将涵盖从安装到基本操作的各个方面&#xff0c;帮助您高效地管理Python环境和依赖项。 Conda 简介 Conda 是一个跨平台的开源包管理器和环境管理器&#xff0c;最初由 Anaconda 开发&#xff0c;广泛用于数据科学、机器学习和科学计算…