• 分布式锁中的基于redis的setnx的原理以及set和setnx的区别是什么


    基于Redis实现分布式锁。虽然网上介绍的Redis分布式锁博客比较多,却有着各种各样的问题,本篇博客将详细介绍如何正确地使用setnx实现Redis分布式锁

    这里就不介绍错误的示范了 大家直接看正确的例子:

    //保存客户端标识
    private static final ThreadLocal<String> LOCAL = new ThreadLocal<String>();
    /**
    *
    * @param jedis
    * @param lockKey 锁key
    * @param expires 过期时间 一般为 System.currentTimeMillis()+ 过期时间
    * @return
    */
    public static boolean getDistributedLock(Jedis jedis, String lockKey, long expires) {
    //客户端标识 在释放锁时 确保由设置锁的客户端来释放自己的锁
    String uuid = UUID.randomUUID().toString();
    LOCAL.set(uuid);
    String expiresStr = uuid+"#"+expires;

    // 如果当前锁不存在,返回加锁成功
    if (jedis.setnx(lockKey, expiresStr) == 1) {
    return true;
    }

    // 如果锁存在,获取锁的过期时间
    String currentValue = jedis.get(lockKey);
    String currentValueStr = null==currentValue?null:currentValue.split("#")[1];
    // 判断当前锁是否过期
    if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
    // 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间 此处多个客户端会覆盖锁的过期时间
    String oldValue = jedis.getSet(lockKey,expiresStr);
    String oldValueStr = null ==oldValue?null:oldValue.split("#")[1];
    // 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才有权利加锁
    if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
    //由于上面会覆盖锁的过期时间 此处让获取锁的客户端 重新设置为自己的过期时间
    jedis.set(lockKey,expiresStr);
    return true;
    }
    }
    // 其他情况,一律返回加锁失败
    return false;
    }

    /**
    *
    * @param jedis
    * @param lockKey 锁key
    * @param value 过期时间 一般为 System.currentTimeMillis()+ 过期时间
    * @return
    */
    public static boolean releaseDistributedLock(Jedis jedis, String lockKey, long value) {
    String uuid = LOCAL.get();
    String valueStr = uuid+"#"+value;
    //根据uuid 这个标识 让客户端 去释放自己的锁 不能释放别人的锁
    if(valueStr.equals(jedis.get(lockKey))){
    jedis.del(lockKey);
    return true;
    }
    return false;
    }

    ————————————————
    版权声明:本文为CSDN博主「wudidewu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wudidewu/article/details/79817125

  • 相关阅读:
    【IoT】IDEA 编译出错 Error running xxx : Command line is too long.Shorten command line
    【可视化】地震剖面道数据可视化绘制思路
    【IoT】使用MQTTBox.exe发送消息到Thingsboard3.3.3上
    【IoT】thingsboard3.3.3测试,使用nodemqtt发送消息
    【IoT】thingsboard3.3.3编译问题解决
    【Postgres】Postgres12帮助手册
    【IoT】发布启动thingsboard3.3.3
    【前端开发】Webpack mars3dvue2electron打包问题
    【可视化】地震数据体Segy文件inline、xline道数据计算获取
    【IoT】thingsboard3.3.3运行启动
  • 原文地址:https://www.cnblogs.com/lingboweifu/p/11807443.html
Copyright © 2020-2023  润新知