分布式锁的Redis实现
2019独角兽企业重金招聘Python工程师标准>>>
分布式锁的代码--redis实现
实现方案
用一个状态值表示锁,对锁的占用和释放通过状态值来标识。
实现思想
- 获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
- 获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
- 释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
核心代码
分布式锁的核心代码如下:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisException;import java.util.List;
import java.util.UUID;public class DistributedLock {private final JedisPool jedisPool;public DistributedLock(JedisPool jedisPool) {this.jedisPool = jedisPool;}/*** 加锁* locaName 锁的key* acquireTimeout 获取超时时间* timeout 锁的超时时间* 锁标识*/public String lockWithTimeout(String locaName,long acquireTimeout, long timeout) {Jedis conn = null;String retIdentifier = null;try {// 获取连接conn = jedisPool.getResource();// 随机生成一个valueString identifier = UUID.randomUUID().toString();// 锁名,即key值String lockKey = "lock:" + locaName;// 超时时间,上锁后超过此时间则自动释放锁int lockExpire = (int)(timeout / 1000);// 获取锁的超时时间,超过这个时间则放弃获取锁long end = System.currentTimeMillis() + acquireTimeout;while (System.currentTimeMillis() < end) {if (conn.setnx(lockKey, identifier) == 1) {conn.expire(lockKey, lockExpire);// 返回value值,用于释放锁时间确认retIdentifier = identifier;return retIdentifier;}// 返回-1代表key没有设置超时时间,为key设置一个超时时间if (conn.ttl(lockKey) == -1) {conn.expire(lockKey, lockExpire);}try {Thread.sleep(10);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}} catch (JedisException e) {e.printStackTrace();} finally {if (conn != null) {conn.close();}}return retIdentifier;}/*** 释放锁* lockName 锁的key* @param identifier 释放锁的标识* @return*/public boolean releaseLock(String lockName, String identifier) {Jedis conn = null;String lockKey = "lock:" + lockName;boolean retFlag = false;try {conn = jedisPool.getResource();while (true) {// 监视lock,准备开始事务conn.watch(lockKey);// 通过前面返回的value值判断是不是该锁,若是该锁,则删除,释放锁if (identifier.equals(conn.get(lockKey))) {Transaction transaction = conn.multi();transaction.del(lockKey);List<Object> results = transaction.exec();if (results == null) {continue;}retFlag = true;}conn.unwatch();break;}} catch (JedisException e) {e.printStackTrace();} finally {if (conn != null) {conn.close();}}return retFlag;}
}
转载于:https://my.oschina.net/grittan/blog/3019886
分布式锁的Redis实现相关推荐
- 分布式锁用 Redis 还是 Zookeeper?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:jianfeng 来源:石杉的架构笔记 为什么用分布式锁? ...
- redis 分布式锁 看门狗_漫谈分布式锁之Redis实现
笔耕墨耘,深研术道. 01写在前面Redis是一个高性能的内存数据库,常用于数据库.缓存和消息中间件.它提供了丰富的数据结构,更适合各种业务场景:基于AP模型,Redis保证了其高可用和高性能. 本文 ...
- 分布式锁用Redis还是Zookeeper?
为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 作者:jianfeng来源:石杉的架构笔记|2019-07-16 09:22 为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场 ...
- java如何保证redis设置过期时间的原子性_分布式锁用 Redis 还是 Zookeeper
在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单. 由于系统有 ...
- 分布式锁用Redis坚决不用Zookeeper?
墨墨导读:为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 为什么用分布式锁? 系统 A 是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查 ...
- redis中有key但是删不掉_分布式锁用 Redis 还是 Zookeeper
为什么用分布式锁? 在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户 ...
- Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析Redis分布式锁的正确使用姿势!...
Redis分布式锁基本原理 采用 redis 实现分布式锁,主要是利用其单线程命令执行的特性,一般是 setnx, 只会有一个线程会执行成功,也就是只有一个线程能成功获取锁:看着很完美. 然而-- 看 ...
- Redis核心数据结构List应用场景-商品列表、缓存击穿、PV阅读量、抢红包、推送帖子、普通分布式锁、Redis可重入锁与红锁
List应用场景 Redis之List 一. Redis list命令实战 二.商品列表 高并发的淘宝聚划算实现技术方案 SpringBoot+Redis实现商品列表功能 二.缓存击穿 什么是缓存击穿 ...
- SpringCloud技术指南系列(十三)分布式锁之Redis实现(redisson)
SpringCloud技术指南系列(十三)分布式锁之Redis实现(redisson) 一.概述 分布式锁是控制分布式系统之间同步访问共享资源的一种方式.在分布式系统中,常常需要协调他们的动作.如果不 ...
- 分布式锁、ZK分布式锁、Redis分布式锁
常见的分布式锁实现方案:ZK分布式锁.Redis分布式锁 ZK分布式锁: 原理:使用ZK 的临时有序节点.节点的监听机制来实现的. 锁特点:悲观锁,公平锁 获取锁:客户端A在/mylock节点目录下创 ...
最新文章
- MATLAB编程经典程序 素数的判断,求0~100素数之和
- 蛋疼的ElasticSearch(一)之安装ElasticSearch
- [python]---从java到python(02)---多线程,队列
- python在材料方面的应用_python记录材料题带标准答案
- 从各位前辈手中搜集的经验
- 织梦++高级搜索php,织梦高级搜索页面advancedsearch.php调用自定义字段
- 02HTML 超链接与图像标记各是什么,【HTML篇】3.HTML的图片标签、超链接标签
- MD1——2 Corner
- 局域网共享工具_[9月17号]局域网环境下文件共享和打印机共享的系统工具软件 局域网共享精灵 V1.0...
- MySQL递归查询 三种实现方式
- 25.jsp之生成二维码
- 超星尔雅不让下载?课件,拿来吧你!
- causal snps | causal variants | tensorflow | 神经网络实战 | Data Simulation
- mongo配置项说明
- 关于铭锐办公系统运行节资统计
- 设计PCB螺旋线圈、电感线圈
- 自行车内胎常识和选购注意事项
- 【项目管理】项目总结会要点和内容
- python判断图片中含有另外一张图
- 宝塔Linux苹果cms安装,苹果CMS V10 全站伪静态教程 伪静态规则分享 宝塔Linux系统...
热门文章
- [特征工程系列五]基于蒙特卡洛搜索树的半自动特征工程方案
- 一起谈.NET技术,浅谈如何使用.NET存储XML数据
- System.Diagnostics.Process.Start()
- 求教大牛!关于后缀树
- 如何实现报表设计中的高精度报表套打?
- OSPF-lsa-types
- 004_URL 路由 - 对磁盘文件的请求进行路由
- **汇总CodeIgniter(CI)的数据库操作函数
- [翻译] ObjectAL for iPhone and Mac(持续更新)
- RIP和OSPF双点双向重发布_综合实验