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     }

  • 相关阅读:
    PHP IDE NetBeans代码主题和除掉竖线解决方案
    初识Python
    从LazyPhp说起
    从Pycharm说起
    准备系统地研究一下"高性能网站开发",挑战很大,希望能坚持到底!
    IIS日志分析[资源]
    见一好东西:Threaded WebDownload class with Progress Callbacks
    ASP.net Application 中使用域用户登录
    看图找错
    汉字转拼音缩写的函数(C#)
  • 原文地址:https://www.cnblogs.com/DevinZhang1990/p/12795197.html
Copyright © 2011-2022 走看看