最近项目又用到分布式锁,下面把自己写的redis分布式锁代码贡献出来。
public class RedisManager {
private static final String SET_IF_NOT_EXIST = "NX";//仅在键不存在时设置键。
private static final String SET_WITH_EXPIRE_TIME = "EX";//PX表示超时时间是毫秒设置,EX表示超时时间是为 second 秒
private static final Long RELEASE_SUCCESS = 1L;
/**
* 单线程独享变量
**/
private ThreadLocal<String> threadLocal = new ThreadLocal<>();
@Autowired
private MergeJedisCmd jedisCmd;
/***
* @param key 键
* @return string
* */
public String get(String key) {
return jedisCmd.get(key);
}
/***
* @param key 键
* @param value 值
* @param expiredTime 秒
* @return true false
* 将 key 的值设为 value ,当且仅当 key 不存在。
* 若给定的 key 已经存在,则 SETNX 不做任何动作。
* */
public boolean set(String key, int expiredTime, String value) {
String result = jedisCmd.setex(key, expiredTime, value);
return result == null ? false : true;
}
/***
* @param key 键
* @param value 值
* @return true false
* 将 key 的值设为 value ,当且仅当 key 不存在。
* 若给定的 key 已经存在,则 SETNX 不做任何动作。
* */
public boolean set(String key, String value) {
return jedisCmd.setnx(key, value) > 0;
}
/**
* 尝试获取分布式锁
*
* @param lockKey 锁
* @param expireTime 超期时间 300(秒)
* @return 是否获取成功
*/
public boolean lock(String lockKey, long expireTime) {
String uuid = UUID.randomUUID().toString();
String value = jedisCmd.set(lockKey, uuid, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (value != null && value.equals("OK")) {
threadLocal.set(uuid);
return true;
}
return false;
}
/**
* 释放分布式锁
* git
*
* @param lockKey 锁
* @return 是否释放成功
*/
public boolean unLock(String lockKey) {
String key = jedisCmd.get(lockKey);
//可能会存在锁失效的时候
if (key == null) {
return true;
}
//保持原子性 (Get —>判断 -> del )操作
String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end ";
Object object = jedisCmd.eval(script, Collections.singletonList(lockKey), Collections.singletonList(threadLocal.get()));
if (RELEASE_SUCCESS.equals(object)) {
return true;
}
return false;
}
由于MergeJedisCmd 是自己项目中封装了,所以大家可以用redis 客户端的原类。
1.MergeJedisCmd extends JedisCmd, BinaryJedisCmd
2.JedisCmd extends JedisCommands, MultiKeyCommands, ScriptingCommands
3.BinaryJedisCmd extends BinaryJedisCommands, MultiKeyBinaryCommands, BinaryScriptingCommands