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);
}
}
}