• SpringBoot 中使用Redis分布式锁


     1 /**
     2      * 获取redis的锁
     3      *
     4      * @param key   键
     5      * @param value 值为当前毫秒数+过期时间毫秒数
     6      * @return 返回true/false
     7      */
     8     public boolean lock(String key, String value) {
     9         if (redisTemplate.opsForValue().setIfAbsent(key, value)) {
    10             //加锁成功就返回true
    11             return true;
    12         }
    13         //不加下面这个可能出现死锁情况
    14         //value为当前时间+超时时间
    15         //获取上一个锁的时间,并判断是否小于当前时间,小于就下一步判断,就返回true加锁成功
    16         //currentValue=A 这两个线程的value都是B 其中一个线程拿到锁
    17         String currentValue = (String) redisTemplate.opsForValue().get(key);
    18         //如果锁过期
    19         if (!StringUtils.isEmpty(currentValue)
    20                 && Long.parseLong(currentValue) < System.currentTimeMillis()) {
    21             //存储时间要小于当前时间
    22             //出现死锁的另一种情况,当多个线程进来后都没有返回true,接着往下执行,执行代码有先后,而if判断里只有一个线程才能满足条件
    23             //oldValue=currentValue
    24             //多个线程进来后只有其中一个线程能拿到锁(即oldValue=currentValue),其他的返回false
    25             //获取上一个锁的时间
    26             String oldValue = (String) redisTemplate.opsForValue().getAndSet(key, value);
    27             if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
    28                 //上一个时间不为空,并且等于当前时间
    29                 return true;
    30             }
    31 
    32         }
    33         return false;
    34     }
    35 
    36 
    37     /**
    38      * redis释放锁
    39      *
    40      * @param key   键
    41      * @param value 值
    42      */
    43     public void unlock(String key, String value) {
    44         //执行删除可能出现异常需要捕获
    45         try {
    46             String currentValue = (String) redisTemplate.opsForValue().get(key);
    47             if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
    48                 //如果不为空,就删除锁
    49                 redisTemplate.opsForValue().getOperations().delete(key);
    50             }
    51         } catch (Exception e) {
    52             log.error("[redis分布式锁] 解锁", e);
    53         }
    54     }

  • 相关阅读:
    204. 计数质数
    236. 二叉树的最近公共祖先
    优先队列和哈夫曼树
    185. 部门工资前三高的所有员工(求组内前几的值)
    部门工资最高的员工(求组内最大值)
    回调函数的案例
    单链表
    动态数组
    一致性哈希算法的基本原理
    只用2GB内存在20亿个整数中找到出现次数最多的数
  • 原文地址:https://www.cnblogs.com/DevinZhang1990/p/12795197.html
Copyright © 2020-2023  润新知