分布式锁实现方案2、基于Redis的SET操作实现的分布式锁
2018-01-22 18:24
896 查看
继上一篇文章 分布式锁实现方案1、基于Redis的SETNX操作实现的分布式锁 实现方案之后,redis又提供了更加强大的set方法,可以解决分布式锁实现方案1中提到的缺陷,直接看代码
package com.alioo.lock; import com.jd.jim.cli.Cluster; import java.util.concurrent.TimeUnit; /** * <pre> * 基于Redis的SET操作实现的分布式锁 * </pre> * * @author lzc.java@icloud.com * */ public class RedisDistributedLock2 { private Cluster redis; // 锁的名字 private String lockKey; private boolean locked; // 当前jvm内持有该锁的线程(if have one) private Thread exclusiveOwnerThread; /** * * @param redis * @param lockKey lockKey * @throws java.io.IOException */ public RedisDistributedLock2(Cluster redis, String lockKey ) { this.redis = redis; this.lockKey = lockKey; } /** * 阻塞式获取锁 ,不过有超时时间,超过了tryGetLockTime还未获取到锁将直接返回false * * @param tryGetLockTime * @param tryGetLockUnit * @return */ protected boolean lock(long tryGetLockTime, TimeUnit tryGetLockUnit) { try { // 超时控制 的时间可以从本地获取, 因为这个和锁超时没有关系, 只是一段时间区间的控制 long start = System.currentTimeMillis(); long timeout = tryGetLockUnit.toMillis(tryGetLockTime); while (System.currentTimeMillis() - start < timeout) { long lockExpireTime = System.currentTimeMillis() + timeout + 1;//锁超时时间 String stringOfLockExpireTime = String.valueOf(lockExpireTime); boolean flag= redis.set(lockKey, stringOfLockExpireTime, tryGetLockTime, tryGetLockUnit, false); if (flag) { // 获取到锁, 设置相关标识 locked = true; exclusiveOwnerThread = Thread.currentThread(); return true; } Thread.sleep(5L); } } catch (InterruptedException e) { e.printStackTrace(); } return false; } /** * 非阻塞,立即返回是否获取到锁 * @return */ public boolean tryLock(long tryGetLockTime, TimeUnit tryGetLockUnit) { long timeout = tryGetLockUnit.toMillis(tryGetLockTime); long lockExpireTime = System.currentTimeMillis() + timeout + 1;//锁超时时间 String stringOfLockExpireTime = String.valueOf(lockExpireTime); boolean flag= redis.set(lockKey, stringOfLockExpireTime, tryGetLockTime, tryGetLockUnit , false); if (flag) { // 获取到锁, 设置相关标识 locked = true; exclusiveOwnerThread = Thread.currentThread(); return true; } return false; } public boolean isLocked() { return locked; } /** * 释放锁 */ public void unlock() { // 检查当前线程是否持有锁 if (Thread.currentThread() != exclusiveOwnerThread) { // 表明锁并非当前线程所持有,不应该由当前线程来释放锁 System.out.println("锁并非当前线程所持有,放弃释放锁exclusiveOwnerThread:" + exclusiveOwnerThread + ",Thread.currentThread():" + Thread.currentThread() + ",lockKey" + lockKey); return; } redis.del(lockKey); exclusiveOwnerThread = null; } }
相关文章推荐
- 分布式锁实现方案1、基于Redis的SETNX操作实现的分布式锁
- 基于redis 实现分布式锁的方案
- Java Jedis操作Redis示例(三)——setnx/getset实现分布式锁
- 分布式锁实现方式二 基于Redis的分布式锁
- 基于 Redis 的分布式缓存实现方案及可靠性加固策略
- Redis分布式锁 基于GETSET SETNX REDISSON 的实现
- 基于redis 实现分布式锁(二)
- 基于redis的分布式锁方案
- 基于Redis实现分布式锁
- 分布式内存数据库---Redis操作String、list、set、hash和Zset
- 基于zookeeper解决分布式锁问题与缓存技术实现分布式锁
- 基于Redis实现分布式锁
- 基于Redis实现简单的分布式锁
- 基于Redis实现的分布式锁
- java 基于redis实现分布式锁
- 基于Redis实现分布式锁
- 基于Redis实现分布式锁
- 基于redis实现的分布式锁
- 基于Redis实现分布式锁
- 基于Redis实现分布式消息队列(2)