Java基于Redis的分布式锁
分布式锁,其实最终还是要保证锁(数据)的一致性,说到数据一致性,基于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); @Autowired
RedisTool 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;
} @Override
public 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);
}
} @Override
public void unlock() {
//释放锁
//不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作
if (isLocked) {
redisManager.releaseDistributedLock(this.key, this.value);
this.isLocked = false;
}
} @Override
public void lockInterruptibly() {
// TODO Auto-generated method stub } @Override
public boolean tryLock() {
// TODO Auto-generated method stub
return false;
} @Override
public boolean tryLock(long time, TimeUnit unit) {
this.expire = unit.toMillis(time);
this.lock();
return this.isLocked;
} @Override
public Condition newCondition() {
// TODO Auto-generated method stub
return 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;
    }
}
Java基于Redis的分布式锁的更多相关文章
- Java基于redis实现分布式锁(SpringBoot)
		
前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...
 - 基于 Redis 的分布式锁
		
前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...
 - 基于redis的分布式锁(转)
		
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
 - 基于redis的分布式锁实现
		
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
 - 基于redis的分布式锁(不适合用于生产环境)
		
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
 - Java使用Redis实现分布式锁来防止重复提交问题
		
如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...
 - redis系列:基于redis的分布式锁
		
一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...
 - 基于redis的分布式锁的分析与实践
		
 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...
 - [Redis] 基于redis的分布式锁
		
前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保 ...
 
随机推荐
- python迭代器、生成器、装饰器之生成器
			
python中只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码,通过__next__()或者next()函数可以获取值,每调用一次,都会取出一个值,无值 ...
 - python:一行代码实现局域网共享文件
			
其实就是使用python内置的一个模块http server 在python2中是下面这样的 python -m SimpleHTTPServer 80 解释下上面的参数,-m表示让python使用一 ...
 - MVC模式实现注册登录
			
很多人对MVC模式搞不懂,刚开始是我也犯迷糊,知道看到一个前辈写的代码,我顿时有的恍然大悟,拿来分享给各位 MVC: 就是M:模型.V:视图(前台界面)C:后台处理的servlet 话不多说.上代码 ...
 - java、ruby、python、php等如何生成excel文档?
			
excel在我们日常工作生活中会经常用到,通常我们都是用office软件去编写文档.但是对于格式一致的excel文档,如果还是使用人工完成,那绝不是我们软件工程师的姿态了~ 下面我就介绍一种方法,不需 ...
 - 【数据库开发】C++测试redis中的publish/subscribe
			
运用 http://blog.csdn.net/xumaojun/article/details/51558237 中的redis_publisher.hredis_publisher.cpp red ...
 - 网络编程(socket).WinSocket_recvfrom出错,GetLastError()为10054
			
1.在写 我的Qt598(vs2017)x64版本的 shadowsocks程序时遇到的. 具体问题情况 大概是这样:QUdpSocket(假设是sktA) connect接收函数,sktA侦听 端口 ...
 - requirejs r.js 打包报错paths fallback not supported in optimizer please provide a build config path override for jquery
			
错误原因: 改为:
 - cv2---imread---error
			
when I use the cv2.imred() which is absolute path path = r'C:\\Users\\hp\\Desktop\\常用Python代码\\mycv ...
 - CentOS7.5下安装nginx --项目部署
			
1.安装ngnix一些依赖包 [root@VM_39_157_centos ~]# yum -y install gcc gcc-c++ openssl-devel pcre-devel httpd- ...
 - 菜单特效jq
			
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...