redis锁的实现,有自己的工具类
import com.yoho8.framework.cache.ICache;
import com.yoho8.framework.cache.bean.Key;
import com.yoho8.framework.enums.ModuleEnum;
import com.yoho8.framework.log.LogUtil;
/**
* @author Create By MengWeiDao 2018/3/14 0014
*/
public class LockUtil {
/**
* 锁失效时间 毫秒 (checkIfLockTimeout方法)
*/
private static final Integer Lock_Timeout = 50;
private ICache cache;
public LockUtil(ICache cache) {
this.cache = cache;
}
/**
* 尝试加锁
* @param lockKey 锁的唯一标识
* @return
*/
private boolean innerTryLock(String lockKey){
Key key = Key.valueOf(ModuleEnum.LOCK,lockKey);
long currentTime = System.currentTimeMillis();
String lockTimeDuration = String.valueOf(currentTime + Lock_Timeout);
Long result = cache.setnx(key, lockTimeDuration);
if(result == 1){
//加锁成功返回true
return true;
}else {
//加锁失败,判断锁是否失效
if(checkIfLockTimeout(currentTime, lockKey)){
//失效,尝试重新set锁,得到上个锁的时间
String preLockTimeDuration = cache.getset(key,lockTimeDuration);
//比较上个锁的时间与当前时间,避免高并发的情况,只有一个返回的是上个锁的时间
if(currentTime > Long.valueOf(preLockTimeDuration)){
//判断,解决高并发竞争问题
return true;
}
}
return false;
}
}
/**
* 对外提供的加锁方法
* @param lockKey 锁标识
* @param timeout 单位:秒 尝试获得锁的有效时间,在这个时间内不断尝试获取锁
* @return
*/
public boolean tryLock(String lockKey, Long timeout){
try{
Long currentTime = System.currentTimeMillis();
boolean result = false;
while (true){
if((System.currentTimeMillis() - currentTime)/1000 > timeout){
//timeout秒后仍然没有获得锁,返回false
LogUtil.info("timeout秒后仍然没有获得锁,返回false");
break;
}else {
//尝试获取锁
result = innerTryLock(lockKey);
if(result){
//加锁成功,返回true
break;
}else {
//100毫秒尝试一次加锁
LogUtil.info("100毫秒尝试一次加锁,lockKey="+lockKey);
Thread.sleep(100);
}
}
}
return result;
}catch (Exception e){
//加锁异常,返回false
LogUtil.info("加锁异常,返回false");
return false;
}
}
/**
* 释放锁
* @param lockKey
*/
public void realseLock(String lockKey){
cache.remove(Key.valueOf(ModuleEnum.LOCK,lockKey));
}
private boolean checkIfLockTimeout(Long currentTime, String lockKey){
Key key = Key.valueOf(ModuleEnum.LOCK,lockKey);
//判断当前时间与锁的时间,判断是否失效
if(currentTime > Long.valueOf(cache.query(key))){
return true;
}else {
return false;
}
}
}