• Redis分布式锁实现


    redis一个命令setnx
    SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写
    将 key 的值设为 value ,当且仅当 key 不存在.
    返回值:
    设置成功,返回 1 。
    设置失败,返回 0 。
    如下思路是设置一个过期锁。但是实际开发中这个过期时间很难判断,需要加守护线程进行重新设置过期时间。
    public boolean tryLock(String key, String requestId, int expireTime) {
    //使用jedis的api,保证原子性
    //NX 不存在则操作 EX 设置有效期,单位是秒
    String result = jedis.set(key, requestId, "NX", "EX", expireTime);
    //返回OK则表示加锁成功
    return "OK".equals(result);
    }
    有一种方法比较靠谱一点,就是给锁续期。在Redisson框架实现分布式锁的思路,就使用watchDog机制实现锁的续期。当加锁成功后,同时开启守护线程,默认有效期是30秒,每隔10秒就会给锁续期到30秒,只要持有锁的客户端没有宕机,就能保证一直持有锁,直到业务代码执行完毕由客户端自己解锁,如果宕机了自然就在有效期失效后自动解锁。

    秒杀场景,幂等返回
    使用自旋操作:

    long timeout = 5000; // 5秒超时秒杀失败
    try {
      Long start = System.currentTimeMillis();
      while(true) {
         String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
         if ("OK".equals(result)) {
            // 秒杀逻辑
            return true;
         }
         
         long time = System.currentTimeMillis() - start;
          if (time>=timeout) {
              return false;
          }
          try {
              Thread.sleep(50);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
    } finally{
        unlock(lockKey,requestId);
    }  
    return false;
    
    
  • 相关阅读:
    .gitignore语法
    每日阅读
    css摘要
    ubuntu安装qq、微信
    django中views中方法的request参数
    js html标签select 中option 删除除了第一行外的其他行
    js 新增标签、标签属性
    python中None与0、Null、false区别
    python class中__init__函数、self
    for foreach循环
  • 原文地址:https://www.cnblogs.com/stubborn-dude/p/14705692.html
Copyright © 2020-2023  润新知