• Java使用Redis来实现分布式锁


    Java使用Redis来实现分布式锁

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

    使用分布式锁!!!

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

    Redisson

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

    1. 引入依赖

      <dependency>
         <groupId>org.redissongroupId>
         <artifactId>redissonartifactId>
         <version>3.16.8version>
      dependency> 
      
      • 1
      • 2
      • 3
      • 4
      • 5
    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);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    3. 创建配置文件

      # Redis 配置
      spring.redis.host=xxx
      spring.redis.port=xxx
      spring.redis.database=xxx
      
      • 1
      • 2
      • 3
      • 4
    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();
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

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

      • waitTime 尝试获取锁的等待时间,超过不再继续获取
      • leaseTime 锁的持有时间,业务代码的执行时间如果超过该时间则抛出异常
        • 可以设置为null 或者 -1 表示业务执行多久占用多久,这里其实使用了看门狗的一个机制,默认的持有时间是30秒,如果超时未执行完成,看门狗会为我们自己续期一次。已保证业务代码执行完成。
      • unit 时间单位
  • 相关阅读:
    Linux命令之文件管理相关命令
    apply()拦截proxy
    什么是栈顶缓存技术
    【算法】传智杯练习赛:平等的交易
    ICCV2021|你以为这是一个填色模型?其实我是检索模型!
    单点登录等功能该用 Keycloak 这种开源框架实现吗?
    nginx的安装(一)
    UDP文件传输工具之UDP怎么限流
    PowerBI - 匹配并从另一个表中获取值
    基于Quartz的可视化UI操作组件GZY.Quartz.MUI更新说明(附:在ABP中集成GZY.Quartz.MUI可视化操作组件)
  • 原文地址:https://blog.csdn.net/qq_43501821/article/details/134537978