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

参考:

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

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

@Component
public class RedisLockManager implements Lock {Logger logger = LoggerFactory.getLogger(RedisLockManager.class);@AutowiredRedisTool redisManager;/*** 请求锁的超时时间(ms)*/private final long TIME_OUT = 30000;/*** 锁的有效时间(毫秒)*/private long expire = 15000;private String key;private String value;private volatile boolean isLocked = false;public void setKey(String key) {this.key = key;}public void setValue(String value) {this.value = value;}@Overridepublic void lock() {//系统当前时间,毫秒long nowTime = System.nanoTime();//请求锁超时时间,毫秒long timeout = TIME_OUT * 1000000;ThreadLocalRandom random = ThreadLocalRandom.current();try {while ((System.nanoTime() - nowTime) < timeout) {boolean flag = redisManager.tryGetDistributedLock(this.key, this.value, this.expire);if (flag) {isLocked = true;//上锁成功结束请求break;}Thread.sleep(3, random.nextInt(500));}} catch (Exception e) {isLocked = false;logger.error(e.getMessage(), e);}}@Overridepublic void unlock() {//释放锁//不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作if (isLocked) {redisManager.releaseDistributedLock(this.key, this.value);this.isLocked = false;}}@Overridepublic void lockInterruptibly() {// TODO Auto-generated method stub
}@Overridepublic boolean tryLock() {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean tryLock(long time, TimeUnit unit) {this.expire = unit.toMillis(time);this.lock();return this.isLocked;}@Overridepublic Condition newCondition() {// TODO Auto-generated method stubreturn null;}
}

@Component
public class RedisTool {

  @Autwire  Jedis jedis;private final String LOCK_SUCCESS = "OK";private final String SET_IF_NOT_EXIST = "NX";private final String SET_WITH_EXPIRE_TIME = "PX";/*** 尝试获取分布式锁* @param jedis Redis客户端* @param lockKey 锁* @param requestId 请求标识* @param expireTime 超期时间* @return 是否获取成功*/public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);if (LOCK_SUCCESS.equals(result)) {return true;}return false;}private final Long RELEASE_SUCCESS = 1L;/*** 释放分布式锁* @param jedis Redis客户端* @param lockKey 锁* @param requestId 请求标识* @return 是否释放成功*/public boolean releaseDistributedLock(String lockKey, String requestId) {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));if (RELEASE_SUCCESS.equals(result)) {return true;}return false;}}

转载于:https://www.cnblogs.com/fqybzhangji/p/11394962.html

Java基于Redis的分布式锁相关推荐

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

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

  2. Java基于Redis实现分布式锁(原子性操作、续命)——90%以上都搞错了

    在使用分布式锁之前,要先思考一个问题,我们为什么要使用分布式锁? 这是因为,在分布式的部署环境下,原来的这个synchronized 只能在当前的JVM中加锁,不能跨JVM实现加锁,所以这种情况下我们 ...

  3. 基于 Redis 实现分布式锁思考

    以下文章来源方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/xuan_lu/article/details/111600302 分布式锁 基于redis实 ...

  4. nx set 怎么实现的原子性_基于Redis的分布式锁实现

    前言 本篇文章主要介绍基于Redis的分布式锁实现到底是怎么一回事,其中参考了许多大佬写的文章,算是对分布式锁做一个总结 分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问 ...

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

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

  6. js 拉勾网效果_Node.js 中实践基于 Redis 的分布式锁实现

    在一些分布式环境下.多线程并发编程中,如果对同一资源进行读写操作,避免不了的一个就是资源竞争问题,通过引入分布式锁这一概念,可以解决数据一致性问题. 作者简介:五月君,Nodejs Developer ...

  7. 基于Redis的分布式锁实现

    本文转自 一.分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问,Java中我们一般可以使用synchronized语法和ReetrantLock去保证,这实际上是本地锁的 ...

  8. redis使用sysc超时_基于redis的分布式锁实现

    随着业务越来越复杂,应用服务都会朝着分布式.集群方向部署,而分布式CAP原则告诉我们,Consistency(一致性). Availability(可用性).Partition tolerance(分 ...

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

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

最新文章

  1. java程序解压/压缩.gz文件
  2. .NET二级域名共享Session
  3. 2021年前端还好找工作吗?
  4. 安装Oracle 11g 出现交换空间不够
  5. 用户空间与内核空间数据交换的方式(2)------procfs
  6. VIIRS SDR数据预处理(二)
  7. C#中的DataGridView
  8. NXP:I2C总线技术规范和用户手册(中文版)(一)
  9. 嵌入式Linux开发工具
  10. 对PID的理解及其实现公式
  11. 逻辑英语语法电子版_11920671英语逻辑语法上.pdf
  12. 数学常用特殊符号读音
  13. idea 类存在,但是报错
  14. python会实现编译功能吗_为什么会有这么多python?其实python并不是编程语言!
  15. 电商项目中的SKU设计,前端后端数据逻辑
  16. CDH安装指南——酒仙网技术
  17. 网络工程师眼中的自动化运维
  18. 古月居ROS入门21讲笔记
  19. Laravel自带SMTP邮件组件实现发送邮件(QQ、163、企业邮箱都可)
  20. MiniUI Api 方法

热门文章

  1. es分页和mysql分页_用户logstash同步mysql数据到es中7.4.1版本以后输出的sql日志中没有分页信息...
  2. php 计算每年春节日期,动态显示2019年农历春节倒计时—2019年1月21日23时45分
  3. Python企业微信机器人
  4. Java 面向对象 之 静态内部类
  5. Java 线程详解(一)线程的基础
  6. Spring AOP体系学习
  7. python处理LINUX的PWD文档
  8. 通过binlog恢复mysql备份之前的数据
  9. Redis2.8的安装教程,linux下
  10. 使用 IntraWeb (41) - 数据控件速查