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

Java使用Redis来实现分布式锁

Java使用Redis来实现分布式锁

在单节点服务中,我们可以使用synchronized来保证同一时间内只允许一个线程执行限定的代码块。但是如果我们是多节点服务呢,因为synchronized是针对服务内部的,其他服务是无法受到他的干预的。那么如何保证多个节点在同一时间内只允许一个节点中的一个线程去访问这个代码块呢?

使用分布式锁!!!

本文使用Redisson来操作Redis并实现分布式锁

Redisson

官网:https://github.com/redisson/redisson/tree/redisson-3.16.8

  1. 引入依赖

    <dependency>
       <groupId>org.redisson</groupId>
       <artifactId>redisson</artifactId>
       <version>3.16.8</version>
    </dependency> 
    
  2. 创建RedissonConfig配置类

    @ConfigurationProperties(prefix = "spring.redis")
    @Configuration
    @Data
    public class RedissonConfig {
        // 主机名
        private String host;
        // 端口
        private String port;
        // 使用那个数据库
        private Integer database;
    
        @Bean
        public RedissonClient redissonClient(){
            Config config = new Config();
            // 使用单机Redis服务
            config.useSingleServer()
                    // use "rediss://" for SSL connection
                    .setAddress(String.format("redis://%s:%s",host,port))
                    .setDatabase(database);
            return Redisson.create(config);
        }
    }
    
  3. 创建配置文件

    # Redis 配置
    spring.redis.host=xxx
    spring.redis.port=xxx
    spring.redis.database=xxx
    
  4. 在业务代码中添加分布式锁

    // 注入我们的RedissonClient
    @Autowired
    private RedissonClient redissonClient;
    
    {
        // 指定一个key来获取锁,如果是需要按不同的情况加锁的话,这样可以使用变量
        RLock lock = redissonClient.getLock("LOCK_NAME");
        try{
            lock.tryLock(long waitTime, long leaseTime, TimeUnit unit);
            //... 业务逻辑
        }catch (InterruptedException ex) {
            ex.printStackTrace();
        }finally{
            // 判断是否由当前线程持有锁 
            if (lock.isHeldByCurrentThread()) {
                // 释放锁
                lock.unlock();
            }
        }
    }
    

    tryLock 尝试获取锁 获取成功返回true 获取失败返回false

    • waitTime 尝试获取锁的等待时间,超过不再继续获取
    • leaseTime 锁的持有时间,业务代码的执行时间如果超过该时间则抛出异常
      • 可以设置为null 或者 -1 表示业务执行多久占用多久,这里其实使用了看门狗的一个机制,默认的持有时间是30秒,如果超时未执行完成,看门狗会为我们自己续期一次。已保证业务代码执行完成。
    • unit 时间单位

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

相关文章:

  • 为何VisualRules更适合技术人员使用
  • Mybatis-plus-Join--分页查询
  • 批量DWG文件转dxf(CAD图转dxf)——c#插件实现
  • linux----系统i/o
  • 力扣438-找到字符串中所有字母异位词
  • OpenCV相机标定与3D重建(23)用于在图像上绘制世界坐标系的三条轴函数drawFrameAxes()的使用
  • 什么是EVM?以太坊EVM合约交互
  • C++之type traits
  • java:简单入门定时任务的几种方式Timer、Quartz、Spring Task
  • Open AI开发者大会:AI“科技春晚”
  • 使用SpringBoot开发一个API网关
  • 设计模式(二)-创建者模式(4)-原型模式
  • 纽扣电池/含纽扣电池产品上架亚马逊各国法规标准要求16 CFR 第 1700.15/20 ANSI C18.3M(瑞西法案认证)
  • vue-awesome-swiper 引入css样式文件报错等问题
  • 前端语言报错
  • 黑马React18: 基础Part II
  • 部署Kubernetes Dashboard
  • 创建域名邮箱邮件地址的方法与步骤
  • vue动态获取目录结构进行配置静态路由
  • Android项目更新依赖和打包步骤和问题汇总
  • 本地部署 EmotiVoice易魔声 多音色提示控制TTS
  • zookeeper应用之分布式队列
  • 百度地图,地市区域描边
  • HTML+CSS+ElementUI搭建个人博客页面(纯前端)
  • 基于STM32CubeMX和keil采用RTC时钟周期唤醒和闹钟实现LED与BEEP周期开关
  • LeetCode977.有序数组的平方(双指针法、暴力法、列表推导式)