基于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. 基于初始种子自动选取的区域生长(python+opencv)

    算法中,初始种子可自动选择(通过不同的划分可以得到不同的种子,可按照自己需要改进算法),图分别为原图(自己画了两笔为了分割成不同区域).灰度图直方图.初始种子图.区域生长结果图.另外,不管时初始种子选 ...

  2. 【POJ2376】Cleaning Shifts

    题目大意:区间最小覆盖问题. 题解:本身是一道贪心水题,但是细节还是比较多的,记录一下. 由于每个奶牛对答案的贡献是一样的,肯定要选择在满足条件的基础上能够拓展最多的那个奶牛.为了满足条件,对区间左端 ...

  3. 有关 CMMI

    CMMI的全称为Capability Maturity Model Integration,即能力成熟度模型集成.CMMI是CMM模型的最新版本.早期的CMMI(CMMI-SE/SW/IPPD),SE ...

  4. CSS三角的写法(兼容IE6)

    目录 简介 优点 原理 1. 先创建一个div 2. 然后给div设定边框. 3. 给div的四个边框都设置不同的颜色 4. 把宽度和高度都变成0 5. 其余角为透明 6. 兼容IE6浏览器 造成这样 ...

  5. vue cli3.0快速搭建项目详解(强烈推荐)

    这篇文章主要介绍下vue-cli3.0项目搭建,项目结构和配置等整理一下,分享给大家. 一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cl ...

  6. dlsym用法

    1. 包含头文件 #include<dlfcn.h> 2. 函数定义 void *dlsym(void *handle, const char* symbol); handle是使用dlo ...

  7. golang之 Array(数组)

    目录 一.Array(数组) 二.数组的定义 1. 基本语法 三.数组的初始化 1. 方式一 2. 方式二 3. 方式三 四.数组的遍历 1. 方式一:for循环遍历 2. 方式二:for range ...

  8. PyPy初体验

    PyPy初体验 PyPy安装 1.下载 下载地址:http://pypy.org/download.html(温馨提示:需要梯子) 下载PyPy3.6 64bit Ubuntu版本 解压 下载下来的文 ...

  9. 初学者的springmvc笔记02

    springmvc笔记 springmvc拦截器,spring类型转换,spring实现文件上传/下载 1.SpringMVC标准配置 导入jar包:core contaner 在web.xml文件中 ...

  10. MySQL--关于MySQL的那些练习题

    之前联系了一些MySQL的查询相关知识,现在补充作为一个记录,免得自己忘记. 致谢博主:https://blog.csdn.net/dehu_zhou/article/details/52881587 ...