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