您的位置:首页 > 数据库 > Redis

分布式锁实现方案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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis 分布式锁