• 基于redis的分布式锁实现方案--redisson


    实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill

    redis官方文档地址,请前往:http://www.redis.cn/topics/distlock.html

    前言

    关于分布式锁的实现,目前主流方案有以下三类:

    1、基于数据库的乐观锁;

    2、基于redis实现的锁服务;

    3、基于zookeeper的实现;

    网上关于怎么实现redis的分布式锁,一搜一大把的文章,有写的比较好的,也有明显存在缺陷的,非常容易误导初入这一块的初学者;

    而存在的问题,无外乎是setnx()-->expire(),保证不了原子性,容易出现死锁等情况,这里就不在去做解释了;

    本文的主旨是如何使用redis官方推荐的redisson实现redis的分布式锁;

    一、具体实现:

    maven引入需要的jar

    1 <dependency>
    2     <groupId>org.redisson</groupId>
    3     <artifactId>redisson-spring-boot-starter</artifactId>
    4     <version>3.10.1</version>
    5 </dependency>

    配置文件如下

    # common spring boot settings
    
    spring.redis.database=
    spring.redis.host=
    spring.redis.port=
    spring.redis.password=
    spring.redis.ssl=
    spring.redis.timeout=
    spring.redis.cluster.nodes=
    spring.redis.sentinel.master=
    spring.redis.sentinel.nodes=

    封装工具类:

      1 package cn.com.bluemoon.redis.lock;
      2 
      3 import java.util.concurrent.TimeUnit;
      4 
      5 import org.redisson.api.RLock;
      6 import org.redisson.api.RedissonClient;
      7 import org.springframework.beans.factory.annotation.Autowired;
      8 import org.springframework.stereotype.Component;
      9 
     10 /**
     11  * 基于Redisson的分布式锁实现
     12  * @author Guoqing.Lee
     13  * @date 2019年1月23日 下午4:04:57
     14  *
     15  */
     16 @Component
     17 public class RedissonDistributedLocker {
     18     
     19     @Autowired
     20     private RedissonClient redissonClient;
     21     
     22     /**
     23      * 加锁
     24      * @param lockKey
     25      * @return
     26      */
     27     public RLock lock(String lockKey) {
     28         RLock lock = redissonClient.getLock(lockKey);
     29         lock.lock();
     30         return lock;
     31     }
     32     
     33     /**
     34      * 加锁,过期自动释放
     35      * @param lockKey
     36      * @param leaseTime    自动释放锁时间
     37      * @return
     38      */
     39     public RLock lock(String lockKey, long leaseTime) {
     40         RLock lock = redissonClient.getLock(lockKey);
     41         lock.lock(leaseTime, TimeUnit.SECONDS);
     42         return lock;
     43     }
     44     
     45     /**
     46      * 加锁,过期自动释放,时间单位传入
     47      * @param lockKey
     48      * @param unit        时间单位
     49      * @param leaseTime    上锁后自动释放时间
     50      * @return
     51      */
     52     public RLock lock(String lockKey, TimeUnit unit, long leaseTime) {
     53         RLock lock = redissonClient.getLock(lockKey);
     54         lock.lock(leaseTime, unit);
     55         return lock;
     56     }
     57     
     58     /**
     59      * 尝试获取所
     60      * @param lockKey
     61      * @param unit        时间单位
     62      * @param waitTime    最多等待时间
     63      * @param leaseTime    上锁后自动释放时间
     64      * @return
     65      */
     66     public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
     67         RLock lock = redissonClient.getLock(lockKey);
     68         try {
     69             return lock.tryLock(waitTime, leaseTime, unit);
     70         } catch (InterruptedException e) {
     71             return false;
     72         }
     73     }
     74     
     75     /**
     76      * 尝试获取所
     77      * @param lockKey
     78      * @param waitTime    最多等待时间
     79      * @param leaseTime    上锁后自动释放锁时间
     80      * @return
     81      */
     82     public boolean tryLock(String lockKey, long waitTime, long leaseTime) {
     83         RLock lock = redissonClient.getLock(lockKey);
     84         try {
     85             return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
     86         } catch (InterruptedException e) {
     87             return false;
     88         }
     89     }
     90     
     91     /**
     92      * 释放锁
     93      * @param lockKey
     94      */
     95     public void unlock(String lockKey) {
     96         RLock lock = redissonClient.getLock(lockKey);
     97         lock.unlock();
     98     }
     99     
    100     /**
    101      * 释放锁
    102      * @param lock
    103      */
    104     public void unlock(RLock lock) {
    105         lock.unlock();
    106     }
    107     
    108 }

    二、使用方式

    方式一:

     1     @Autowired
     2     private RedissonDistributedLocker redissonDistributedLocker;
     3 
     4         String lockKey = "BM_MARKET_SECKILL_" + stallActivityId;
     5     try {
     6                 //超过2S自动释放锁
     7         redissonDistributedLocker.lock(lockKey, 2L);
     8                 //业务处理
     9 
    10         } finally {
    11         redissonDistributedLocker.unlock(lockKey);  //释放锁
    12     }    

    方案二:

     1 @Autowired
     2 private RedissonDistributedLocker redissonDistributedLocker;
     3 
     4 public void test() throws InterruptedException {
     5     final int[] counter = {0};
     6 
     7         for (int i= 0; i < 100; i++){
     8         
     9             new Thread(new Runnable() {
    10 
    11                 @Override
    12 
    13                 public void run() {
    14                     boolean isGetLock = redissonDistributedLocker.tryLock("test0001", 3L, 1L);
    15                     if(isGetLock) {
    16                         try {
    17                             int a = counter[0];
    18                             counter[0] = a + 1;
    19                             logger.info(a + "");
    20                         } finally {
    21                             redissonDistributedLocker.unlock("test0001");
    22                         }
    23                     }
    24                 }
    25             }).start();
    26             
    27         }
    28 
    29         // 主线程休眠,等待结果
    30         Thread.sleep(5000);
    31         System.out.println(counter[0]);
    32         logger.info(counter[0] + "");
    33 }

    闲话就不多说了,希望能对你有所帮助。

  • 相关阅读:
    背水一战 Windows 10 (61)
    背水一战 Windows 10 (60)
    背水一战 Windows 10 (59)
    背水一战 Windows 10 (58)
    背水一战 Windows 10 (57)
    背水一战 Windows 10 (56)
    背水一战 Windows 10 (55)
    背水一战 Windows 10 (54)
    背水一战 Windows 10 (53)
    背水一战 Windows 10 (52)
  • 原文地址:https://www.cnblogs.com/ocean-sky/p/10320627.html
Copyright © 2020-2023  润新知