redis锁的实现

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

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值