redis+Lua实现分布式锁

1.方法lock(String lock, int expire) :获取锁
expire,锁的过期时间
setnx(),只有当lock不存在时才会赋值,赋值成功返回1,赋值失败返回0

public boolean lock(String lock, int expire) throws Exception {
	Assert.notNull(lock, "lock must not be null");
	long expireTime = getExpireTime(expire);
	return RedisUtils.setnx(lock, expireTime) ==1;
 }

2.方法softUnlock(String lock):解锁,只有当锁过期时才会解锁

使用Lua脚本script,获取锁的状态以及解锁,这两步操作必须为原子性操作

public boolean softUnlock(String lock)throws Exception {
    	Assert.notNull(lock, "lock must not be null");
    	String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) < ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";
   		String currentTime = String.valueOf(System.currentTimeMillis());
   		String expireCode = String.valueOf(RedisUtils.eval(script, lock, currentTime));
   		return RELEASE_SUCCESS.equals(expireCode)
}

3.方法hardUnlock(String lock):解锁,不关心锁的是否过期

public boolean hardUnlock(String lock) throws Exception {
        Assert.notNull(lock, "lock must not be null");
        RedisUtils.del(lock);
        return true;
}

4.方法getLockStatus(String lock):获取锁的状态

public boolean getLockStatus(String lock) throws Exception {
    String value = RedisUtils.get(lock);
    return value ==null || Long.parseLong(value) < System.currentTimeMillis();
}

5.方法autoIncrLock(String lock):锁的值自加1,如果锁本身不存在,默认从0开始

public String autoIncrLock(String lock) throws Exception {
    	Assert.notNull(lock, "lock must not be null");
    	lock = assembleKey(AUTO, lock);
    	String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('incr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";
    	String value = String.valueOf(RedisUtils.eval(script, lock, "1"));
   		 logger.info("autoIncrLock success#lock={},value={}", lock, value);
    	return value;
}

6.方法autoDecrLock(String lock):锁的值自减1,如果锁本身不存在,默认从0开始

public String autoDecrLock(String lock) throws Exception {
    	Assert.notNull(lock, "lock must not be null");
    	lock = assembleKey(AUTO, lock);
    	String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('decr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";
    	String value = String.valueOf(RedisUtils.eval(script, lock, "-1"));
    	logger.info("autoDecrLock success#lock={},value={}", lock, value);
   		 return value;
}

7.方法softUnlockAuto(String lock):解锁,只有当锁过期时才会解锁

public boolean softUnlockAuto(String lock) throws Exception {
    	Assert.notNull(lock, "lock must not be null");
    	lock = assembleKey(AUTO, lock);
    	String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) <= ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";
    	String code = String.valueOf(RedisUtils.eval(script, lock, "0"));         
       return RELEASE_SUCCESS.equals(code);
}

8.方法hardUnlockAuto(String lock):解锁,不关心当前锁的状态

public boolean hardUnlockAuto(String lock) throws Exception {
            lock = assembleKey(AUTO, lock);
            return hardUnlock(lock);
 }

9.方法String assembleKey(String… section):组装key

public String assembleKey(String... section) throw Exception {
  		  List sections =new ArrayList(Arrays.asList(section));
  		  Joiner joiner = Joiner.on(KEY_PRE_CON_SIGN).skipNulls();
 		  return joiner.join(sections);
 }

10.方法getExpireTime(int expire): 获取过期时间

private String getExpireTime(int expire) throws Exception {
    	 Assert.isTrue(expire > 0, "expire must be greater than 0");
   		 long expireTime = System.currentTimeMillis() + expire +1;
   		 return String.valueOf(expireTime);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值