当前位置: 首页 > article >正文

深度剖析 Redisson 分布式锁:原理、实现与应用实践

文章目录

    • 写在文章开头
    • 详解Redisson 分布式锁使用和实现
      • 前置准备工作
      • 分布式锁的基本使用
      • 公平锁的使用
      • 联锁的使用
      • 读写锁基本使用
    • 常见问题
      • Redisson和Jedis有什么区别
      • redisson如何实现分布式锁
      • redisson如何实现分布式锁的可重入
      • redisson如何实现公平锁
      • Redisson的watchdog机制是什么?如何实现的
      • 什么是RedLock,其实现思路是什么
      • Redisson 中为什么要废弃 RedLock
    • 参考

写在文章开头

在当今分布式系统大行其道的技术领域,如何有效协调多个节点之间对共享资源的访问,成了开发者们必须攻克的一道难关。分布式锁,作为解决这一难题的关键技术手段,正发挥着举足轻重的作用。
在众多分布式锁的实现方案中,Redisson 以其强大的功能、出色的性能和极高的易用性脱颖而出,成为了开发者们的得力助手。Redisson 不仅仅是一个简单的分布式锁工具,它更像是一套完整的分布式协调框架,提供了丰富多样的分布式对象和服务,极大地简化了分布式系统的开发过程。

详解Redisson 分布式锁使用和实现

前置准备工作

使用redisson时我们优先需要引入其依赖:

 <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.23.5</version>
        </dependency>

然后配置redis基本配置信息,这里笔者以单体架构为例给出redis的配置示例:

spring.redis.host=localhost
spring.redis.port=6379

分布式锁的基本使用

RLock继承了JUC包下的Lock接口,所以使用起来和JUC包下的几个lock类似,这里我们也给出相应的基本代码示例:


        CountDownLatch countDownLatch = new CountDownLatch(2);


        //声明一把分布式锁
        RLock lock = redissonClient.getLock("lock");

        new Thread(() -> {
   
            try {
   
                //上锁
                lock.lock();

                log.info("lock lock success");
                ThreadUtil.sleep(1, TimeUnit.MINUTES);

                countDownLatch.countDown();
            } catch (Exception e) {
   
                e.printStackTrace();
            } finally {
   
                lock.unlock();
            }
        }).start();


        new Thread(() -> {
   
            try {
   
                //休眠5s让上一个线程先取锁
                ThreadUtil.sleep(5, TimeUnit.SECONDS);

                //上锁
                if (lock.tryLock()) {
   
                    log.info("try  lock success");
                    //成功后执行业务逻辑然后释放锁
                    ThreadUtil.sleep(1, TimeUnit.MINUTES);
                    lock.unlock();
                } else {
   
                    log.info("try lock fail");
                }

                countDownLatch.countDown();
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        }).start();

        countDownLatch.await();

对应的输出结果如下,可以看到第一个线程基于redisson上锁成功后,第二个线程就无法上锁了:

在这里插入图片描述

公平锁的使用

默认情况下redisson分布式锁是非公平的,即任意时刻任意一个请求都可以在锁释放后争抢分布式锁,对此redisson给出了公平锁的实现,如下代码所示,笔者通过getFairLock声明一把公平锁,让声明5个线程进行争抢:

int size = 5;
        //声明分布式锁
        RLock reentrantLock = redissonClient.getFairLock("lock");
        //创建线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(size);

        CountDownLatch countDownLatch = new CountDownLatch(size);

        //遍历线程池,让池内的线程争抢分布式锁
        for (int i = 0; i < size; i++) {
   
            threadPool.submit(() -> {
   
                try {
   
                    reentrantLock.lock();
                    log.info("reentrantLock.lock success");
                } catch (Exception e) {
   
                    log.error("reentrantLock.lock error", e);
                } finally {
   
                    reentrantLock.unlock();
                    log.info("reentrantLock.unlock success");
                    countDownLatch.countDown();
                }
            });
        }

        countDownLatch.await();

可以看到,笔者通过调试的方式顺序让线程争抢分布式锁,最终输出结果也是按照先来后到的方式获取锁和释放锁:

在这里插入图片描述

联锁的使用

联锁顾名思义,只有一次性获取多把锁之后才能算成功,对应的代码示例如下:

RLock lock1 = redissonClient.getFairLock

http://www.kler.cn/a/537556.html

相关文章:

  • 【翻译+论文阅读】DeepSeek-R1评测:粉碎GPT-4和Claude 3.5的开源AI革命
  • Ecahrts前端面试题
  • 设计模式 ->模板方法模式(Template Method Pattern)
  • PHP PDO 教程
  • hot100(9)
  • Elasticsearch:向量搜索的快速介绍
  • k8s部署go-fastdfs
  • OSPF基础(3):区域划分
  • Java 的 CopyOnWriteArrayList 和 Collections.synchronizedList 有什么区别?分别有什么优缺点?
  • 【算法】动态规划专题⑧ —— 分组背包问题 python
  • 《qt6+Open3d点云读取》
  • android apk反编译
  • Verilog 语法篇 硬件描述语言
  • redis高级数据结构布隆过滤器
  • 基于ESP32的远程开关灯控制(ESP32+舵机+Android+物联网云平台)
  • 启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全
  • 跨端兼容——请让我的页面展现在电脑、平板、手机上
  • 运用Deek Seeker协助数据分析
  • 客运自助售票小程序的设计与实现ssm+论文源码调试讲解
  • Python Pandas(5):Pandas Excel 文件操作
  • 服务器重启后报Predis_ServerException: Client sent AUTH, but no password is set
  • C++ 内存顺序与内存模型
  • k8s的操作指令和yaml文件
  • Vue(6)
  • 使用 JFreeChart 创建动态图表:从入门到实战
  • 深入解析 STM32 GPIO:结构、配置与应用实践