基于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

分布式锁中的基于redis的setnx的原理以及set和setnx的区别是什么的更多相关文章

  1. 分布式锁(2) ----- 基于redis的分布式锁

    分布式锁系列文章 分布式锁(1) ----- 介绍和基于数据库的分布式锁 分布式锁(2) ----- 基于redis的分布式锁 分布式锁(3) ----- 基于zookeeper的分布式锁 代码:ht ...

  2. 分布式锁(3) ----- 基于zookeeper的分布式锁

    分布式锁系列文章 分布式锁(1) ----- 介绍和基于数据库的分布式锁 分布式锁(2) ----- 基于redis的分布式锁 分布式锁(3) ----- 基于zookeeper的分布式锁 代码:ht ...

  3. 借读:分布式锁和双写Redis

      本帖最后由 howtodown 于 2016-10-3 16:01 编辑问题导读1.为什么会产生分布式锁?2.使用分布式锁的方法有哪些?3.本文创造的分布式锁的双写Redis框架都包含哪些内容? ...

  4. 分布式锁的实现之 redis 篇

    为什么需要分布式锁 引入经典的秒杀情景,100件商品供客户抢.如果是单机版的话,我们使用synchronized 或者 lock 都可以实现线程安全.但是如果多个服务器的话,synchronized ...

  5. springboot实现分布式锁(spring integration,redis)

    Springboot实现分布式锁(Spring Integration+Redis) 一.在项目的pom.xml中添加相关依赖 1)Spring Integration依赖 <dependenc ...

  6. 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁

    一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...

  7. 分布式锁与实现--基于ZooKeeper实现

    引言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...

  8. 分布式锁实现(一):Redis

    前言 单机环境下我们可以通过JAVA的Synchronized和Lock来实现进程内部的锁,但是随着分布式应用和集群环境的出现,系统资源的竞争从单进程多线程的竞争变成了多进程的竞争,这时候就需要分布式 ...

  9. 分布式锁中的王者方案-Redisson

    上篇讲解了如何用 Redis 实现分布式锁的五种方案,但我们还是有更优的王者方案,就是用 Redisson. 缓存系列文章: 缓存实战(一):20 图 |6 千字|缓存实战(上篇) 缓存实战(二):R ...

随机推荐

  1. Linux服务器安装配置JDK

    一.准备工作: 1.登录服务器,切换到root用户(su - root,然后输入密码,按enter),进入根目录:cd / 2.进入要安装jdk的目录,自己可以创建一个java目录,执行命令如下: c ...

  2. 【2019银川网络赛】L:Continuous Intervals

    题目大意:给定一个长度为 N 的序列,定义连续区间 [l, r] 为:序列的一段子区间,满足 [l, r] 中的元素从小到大排序后,任意相邻两项的差值不超过1.求一共有多少个连续区间. 题解:单调栈 ...

  3. VCL界面控件DevExpress VCL Controls v19.1.3全新来袭

    DevExpress VCL Controls是 Devexpress公司旗下最老牌的用户界面套包.所包含的控件有:数据录入,图表,数据分析,导航,布局,网格,日程管理,样式,打印和工作流等,让您快速 ...

  4. jvm的几篇文章

    https://www.cnblogs.com/xrq730/category/731395.html

  5. nginx部署网站step by step

    安装后,修改nginx.conf,在httpd{}中添加 include /nginx/vhosts/*.conf; 如果没有vhosts就新建一个文件夹 *.conf是一种正则表达式用法,表示纳入一 ...

  6. 【JavaWeb】之Servlet

    一.Servlet简介 1.1 什么是Servlet(server applet): 是一种独立于平台和协议的服务器端Java应用程序,通过Servlet可以生成动态web页面.还可以在服务器端对客户 ...

  7. CSS 的伪元素是什么?

    CSS伪元素是用来添加一些选择器的特殊效果.用于:向某个选择器中的文字的首行. ㈠语法 ①伪元素的语法: selector:pseudo-element {property:value;} ②CSS类 ...

  8. docker部署war+tomcat8

    注意:本文只是将jenkins.war作为一个war包来操作,实际上要使用jenkins还要同时安装git.maven等. 1.购买阿里云服务器(Ubuntu 18.04), 设置密码,root+pa ...

  9. 4.JSP内置对象

    JSP内置对象,JSP提供了由容器实现和管理的内置对象,也可以称之为隐含对象,这些内置对象不需要通过 JSP页面编写来实例化,在所有的JSP页面中都可以直接使用,它起到了简化页面的作用. 在JSP中一 ...

  10. MCMC & 贝叶斯

    用MCMC做参数估计