分布式锁,其实最终还是要保证锁(数据)的一致性,说到数据一致性,基于ZK,ETCD数据一致性中间件做分数是锁,才是王道。但是Redis也能满足最基本的需求。

参考:

https://www.cnblogs.com/technologykai/p/8658689.html

https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_1003days.html

  1. @Component
  2. public class RedisLockManager implements Lock {
  3. Logger logger = LoggerFactory.getLogger(RedisLockManager.class);
  4.  
  5. @Autowired
  6. RedisTool redisManager;
  7. /**
  8. * 请求锁的超时时间(ms)
  9. */
  10. private final long TIME_OUT = 30000;
  11. /**
  12. * 锁的有效时间(毫秒)
  13. */
  14. private long expire = 15000;
  15. private String key;
  16. private String value;
  17.  
  18. private volatile boolean isLocked = false;
  19.  
  20. public void setKey(String key) {
  21. this.key = key;
  22. }
  23.  
  24. public void setValue(String value) {
  25. this.value = value;
  26. }
  27.  
  28. @Override
  29. public void lock() {
  30. //系统当前时间,毫秒
  31. long nowTime = System.nanoTime();
  32. //请求锁超时时间,毫秒
  33. long timeout = TIME_OUT * 1000000;
  34. ThreadLocalRandom random = ThreadLocalRandom.current();
  35. try {
  36. while ((System.nanoTime() - nowTime) < timeout) {
  37. boolean flag = redisManager.tryGetDistributedLock(this.key, this.value, this.expire);
  38. if (flag) {
  39. isLocked = true;
  40. //上锁成功结束请求
  41. break;
  42. }
  43. Thread.sleep(3, random.nextInt(500));
  44. }
  45. } catch (Exception e) {
  46. isLocked = false;
  47. logger.error(e.getMessage(), e);
  48. }
  49. }
  50.  
  51. @Override
  52. public void unlock() {
  53. //释放锁
  54. //不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作
  55. if (isLocked) {
  56. redisManager.releaseDistributedLock(this.key, this.value);
  57. this.isLocked = false;
  58. }
  59. }
  60.  
  61. @Override
  62. public void lockInterruptibly() {
  63. // TODO Auto-generated method stub
  64.  
  65. }
  66.  
  67. @Override
  68. public boolean tryLock() {
  69. // TODO Auto-generated method stub
  70. return false;
  71. }
  72.  
  73. @Override
  74. public boolean tryLock(long time, TimeUnit unit) {
  75. this.expire = unit.toMillis(time);
  76. this.lock();
  77. return this.isLocked;
  78. }
  79.  
  80. @Override
  81. public Condition newCondition() {
  82. // TODO Auto-generated method stub
  83. return null;
  84. }
  85. }
  1.  
  1. @Component
  1. public class RedisTool {
  2.  
  3.   @Autwire
      Jedis jedis;
  4.  
  5. private final String LOCK_SUCCESS = "OK";
  6. private final String SET_IF_NOT_EXIST = "NX";
  7. private final String SET_WITH_EXPIRE_TIME = "PX";
  8.  
  9. /**
  10. * 尝试获取分布式锁
  11. * @param jedis Redis客户端
  12. * @param lockKey 锁
  13. * @param requestId 请求标识
  14. * @param expireTime 超期时间
  15. * @return 是否获取成功
  16. */
  17. public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
  18.  
  19. String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
  20.  
  21. if (LOCK_SUCCESS.equals(result)) {
  22. return true;
  23. }
  24. return false;
  25.  
  26. }
  27.  
  28. private final Long RELEASE_SUCCESS = 1L;
  29.  
  30. /**
  31. * 释放分布式锁
  32. * @param jedis Redis客户端
  33. * @param lockKey 锁
  34. * @param requestId 请求标识
  35. * @return 是否释放成功
  36. */
  37. public boolean releaseDistributedLock(String lockKey, String requestId) {
  38.  
  39. String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
  40. Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
  41.  
  42. if (RELEASE_SUCCESS.equals(result)) {
  43. return true;
  44. }
  45. return false;
  46.  
  47. }
  48.  
  49. }

Java基于Redis的分布式锁的更多相关文章

  1. Java基于redis实现分布式锁(SpringBoot)

    前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...

  2. 基于 Redis 的分布式锁

    前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...

  3. 基于redis的分布式锁(转)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  4. 基于redis的分布式锁实现

    1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...

  5. 基于redis的分布式锁(不适合用于生产环境)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  6. Java使用Redis实现分布式锁来防止重复提交问题

    如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...

  7. redis系列:基于redis的分布式锁

    一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...

  8. 基于redis的分布式锁的分析与实践

    ​ 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...

  9. [Redis] 基于redis的分布式锁

    前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保 ...

随机推荐

  1. easyui-datagrid配置宽度高度自适应

    在style属性中,去除之前添加的width和height属性(如果有的话),然后添加"fit:false"即可.

  2. QuickText for Notepad++

    昨刚投入新欢Notepad++,思路如泉涌,码代码也不累了,一口气用她码了两篇文- 今再接再厉,继续.QuickText严格说来算不上什么神器级插件,也仅只是一个缩写快捷输入的插件而已.可用得好,那效 ...

  3. django:bootstrap table加载django返回的数据

    bootstrap table加载表格数据有两类方式: 一种通过data属性的方式配置,一种是javascipt方式配置 这里看js配置方式: 1.当数据源为.json文件时 url参数写上json文 ...

  4. 共享文件word / excel /ppt 被用戶自己锁定无法编辑-解決方法

    共享文件word / excel /ppt 被用戶自己鎖定無法編輯,但用戶嘗試過關閉所有文件和重啓過系統,依然無法編輯. 搜到解決方法: Just in case someone looking fo ...

  5. 【POJ - 2010】Moo University - Financial Aid(优先队列)

    Moo University - Financial Aid Descriptions 奶牛大学:奶大招生,从C头奶牛中招收N(N为奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新 ...

  6. CTF 专用文件监控系统

    # -*- coding: utf-8 -*-#use: python file_check.py ./ import osimport hashlibimport shutilimport ntpa ...

  7. [转帖]HTTP请求方法:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE 说明

    HTTP请求方法:GET.HEAD.POST.PUT.DELETE.CONNECT.OPTIONS.TRACE 说明 平时的Rest开发,用到的都是GET,POST,PUT,DELETE类型的请求. ...

  8. 基于requests模块的代理

    1.什么是代理? ​ 代理:将网络请求发送给代理服务器,通过代理服务器做中介,将请求转发给目标服务器并将响应返回,从而完成网络通信. 2.为什么使用代理? ​ 使用爬虫抓取批量资源时,在短时间内会对服 ...

  9. Swarm系列7--存储介绍

    存储介绍 1. 存储使用 与docker一样,在使用swarm服务级别的时候可以定义服务的存储需求, docker存储介绍参考: Docker之应用数据管理(volume/bind mount/tmp ...

  10. Django 中 app_name (应用命名空间) 和 namespace (实例命名空间) 的区别

    转自:https://www.jianshu.com/p/404500a0408a 补充理解: 先把官网上对应用命名空间(app_name)和实例命名空间(namespace)的解释贴上: app_n ...