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实现相关推荐

  1. 分布式锁用 Redis 还是 Zookeeper?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:jianfeng 来源:石杉的架构笔记 为什么用分布式锁? ...

  2. redis 分布式锁 看门狗_漫谈分布式锁之Redis实现

    笔耕墨耘,深研术道. 01写在前面Redis是一个高性能的内存数据库,常用于数据库.缓存和消息中间件.它提供了丰富的数据结构,更适合各种业务场景:基于AP模型,Redis保证了其高可用和高性能. 本文 ...

  3. 分布式锁用Redis还是Zookeeper?

    为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 作者:jianfeng来源:石杉的架构笔记|2019-07-16 09:22 为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场 ...

  4. java如何保证redis设置过期时间的原子性_分布式锁用 Redis 还是 Zookeeper

    在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单. 由于系统有 ...

  5. 分布式锁用Redis坚决不用Zookeeper?

    墨墨导读:为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 为什么用分布式锁? 系统 A 是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查 ...

  6. redis中有key但是删不掉_分布式锁用 Redis 还是 Zookeeper

    为什么用分布式锁? 在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户 ...

  7. Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析Redis分布式锁的正确使用姿势!...

    Redis分布式锁基本原理 采用 redis 实现分布式锁,主要是利用其单线程命令执行的特性,一般是 setnx, 只会有一个线程会执行成功,也就是只有一个线程能成功获取锁:看着很完美. 然而-- 看 ...

  8. Redis核心数据结构List应用场景-商品列表、缓存击穿、PV阅读量、抢红包、推送帖子、普通分布式锁、Redis可重入锁与红锁

    List应用场景 Redis之List 一. Redis list命令实战 二.商品列表 高并发的淘宝聚划算实现技术方案 SpringBoot+Redis实现商品列表功能 二.缓存击穿 什么是缓存击穿 ...

  9. SpringCloud技术指南系列(十三)分布式锁之Redis实现(redisson)

    SpringCloud技术指南系列(十三)分布式锁之Redis实现(redisson) 一.概述 分布式锁是控制分布式系统之间同步访问共享资源的一种方式.在分布式系统中,常常需要协调他们的动作.如果不 ...

  10. 分布式锁、ZK分布式锁、Redis分布式锁

    常见的分布式锁实现方案:ZK分布式锁.Redis分布式锁 ZK分布式锁: 原理:使用ZK 的临时有序节点.节点的监听机制来实现的. 锁特点:悲观锁,公平锁 获取锁:客户端A在/mylock节点目录下创 ...

最新文章

  1. MATLAB编程经典程序 素数的判断,求0~100素数之和
  2. 蛋疼的ElasticSearch(一)之安装ElasticSearch
  3. [python]---从java到python(02)---多线程,队列
  4. python在材料方面的应用_python记录材料题带标准答案
  5. 从各位前辈手中搜集的经验
  6. 织梦++高级搜索php,织梦高级搜索页面advancedsearch.php调用自定义字段
  7. 02HTML 超链接与图像标记各是什么,【HTML篇】3.HTML的图片标签、超链接标签
  8. MD1——2 Corner
  9. 局域网共享工具_[9月17号]局域网环境下文件共享和打印机共享的系统工具软件 局域网共享精灵 V1.0...
  10. MySQL递归查询 三种实现方式
  11. 25.jsp之生成二维码
  12. 超星尔雅不让下载?课件,拿来吧你!
  13. causal snps | causal variants | tensorflow | 神经网络实战 | Data Simulation
  14. mongo配置项说明
  15. 关于铭锐办公系统运行节资统计
  16. 设计PCB螺旋线圈、电感线圈
  17. 自行车内胎常识和选购注意事项
  18. 【项目管理】项目总结会要点和内容
  19. python判断图片中含有另外一张图
  20. 宝塔Linux苹果cms安装,苹果CMS V10 全站伪静态教程 伪静态规则分享 宝塔Linux系统...

热门文章

  1. [特征工程系列五]基于蒙特卡洛搜索树的半自动特征工程方案
  2. 一起谈.NET技术,浅谈如何使用.NET存储XML数据
  3. System.Diagnostics.Process.Start()
  4. 求教大牛!关于后缀树
  5. 如何实现报表设计中的高精度报表套打?
  6. OSPF-lsa-types
  7. 004_URL 路由 - 对磁盘文件的请求进行路由
  8. **汇总CodeIgniter(CI)的数据库操作函数
  9. [翻译] ObjectAL for iPhone and Mac(持续更新)
  10. RIP和OSPF双点双向重发布_综合实验