zoukankan      html  css  js  c++  java
  • 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     }

  • 相关阅读:
    获得oc支持的国家和语言
    在iOS开发中,经常需要调用其它App,如拨打电话、发送邮件等。UIApplication:openURL:方法是实现这一目的的 ##转
    UITableView的分组 快速索引
    xcode调试技巧
    组件data中必须是function的原因
    组件中的 data 和methods
    使用 components 定义私有组件
    使用 transition-group 元素实现列表动画
    组件化和模块化
    使用钩子函数模拟小球半场动画
  • 原文地址:https://www.cnblogs.com/DevinZhang1990/p/12795197.html
Copyright © 2011-2022 走看看