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

redis实现分布式锁

2017-09-15 13:21 120 查看

       最近公司使用Dubbo框架进行项目开发,在开发过程中遇到了线程同步问题,在网上查找了大部分资料后,发现可以使用redis或者zookeeper实现分布式锁,虽然有些帖子写的不错并给出了实现方案,但是自己在仔细推敲琢磨后发现其中还是有些逻辑问题,于是自己便动手写了一个,直接上代码。

一、首先需了解redis的几个方法

1、setnx(key,value)如果redis数据库中不存在key,将key的值设为value,返回1;key存在时,不做任何操作,返回0

2、getset(key,value)将key的值设为value并返回旧值,如果key不存在则返回null

3、del(key)删除key

二、代码实现

               

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @ClassName: DistributedLockHandler.java
* @Description: 分布式锁工具类
* @Author:xiaoping
* @CreateDate 2017年9月8日
* @version:1.0
*
*/

public class DistributedLockHandler {

private static Logger logger = LoggerFactory.getLogger(DistributedLockHandler.class);
private static final Integer Lock_Timeout = 3;
private static final Map<String, String> map=new ConcurrentHashMap<String, String>();

/**
* 获取指定数据库的锁资源
*@param lockKey
*@param market
*@return
*/
private static boolean innerTryLock(String lockKey, int market) {

boolean isSuccess = false;
long currentTime = System.currentTimeMillis();
String lockTimeDuration = String.valueOf(currentTime + Lock_Timeout + 1);
long result = RedisUtil.setnx(lockKey, lockTimeDuration, market);
if (result == 1) {
isSuccess = true;
map.put(lockKey, lockTimeDuration);
} else {
long oldValue = Long.valueOf(RedisUtil.get(lockKey, market));
if (oldValue < System.currentTimeMillis()) {
long getValue = Long.valueOf(RedisUtil.getSet(lockKey, lockTimeDuration, market));
if (getValue == oldValue) {
isSuccess = true;
map.put(lockKey, lockTimeDuration);
} else {
isSuccess = false;
}
} else {
isSuccess = false;
}
}
return isSuccess;
}

/**
* 获取指定数据库的锁资源,并指定超时时间
*@param lockKey
*@param timeOut
*@param market
*@return
*/
public static boolean tryLock(String lockKey, Long timeOut, int market) {

try {
long currentTime = System.currentTimeMillis();
boolean result = false;
while (true) {
if ((System.currentTimeMillis() - currentTime) / 1000 > timeOut) {
logger.info("Execute DistributedLockHandler.tryLock method, Time out.");
break;
} else {
result = innerTryLock(lockKey, market);
if (result) {
break;
} else {
logger.debug("Try to get the Lock,and wait 100 millisecond....");
Thread.sleep(100);
}
}

}
return result;

} catch (Exception e) {
logger.error("Failed to run DistributedLockHandler.getLock method.", e);
return false;
}

}

/**
* 释放指定数据库的锁资源
*@param lockKey
*@param currentTime
*@param market
*/
public void realseLock(String lockKey, long currentTime, int market) {
String lockTimeDuration = RedisUtil.get(lockKey, market);
if (map.get(lockKey)!=null&&map.get(lockKey).equals(lockTimeDuration)){
RedisUtil.del(lockKey, market);
map.remove(lockKey);
}
}

}


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