突然需要用到redis锁了,发现还没写过,写个简单的玩
不多说废话了,直接开整,(废话在今天另外一个帖子说完了,哈哈)
public class RedisUtil{
private static JedisentinelPool pool = null;
private static final String luaScript=" if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end ";
private static final int TIME_OUT=60*1000;
public static boolean noLock(String key, String value){
//判断参数是否为空,加强控制的,没事大作用
if(StringUtil.isBlank(key) || StringUtil.isBlank(value)){
return false;
}
}
//加锁
public static boolean lock(String key, String value){
Jedis jedis =null;
try{
jedis= getJedis();//从jedisPool连接池获取连接的,自己找,这里不写了
while(flag){
if("OK".equals(jedis.set(key,value,"nx","px",TIME_OUT))){
false=false;
}else{
System.out.print("lock exists, waiting...")
Thread.sleep((int)Math.random()*50+50);
}
}
}catch(Exception e){
//TODO
return true;
}finally{
jedis.close();
}
return true;
}
//解锁
public static boolean deleteLock(String key, String value){
if(StringUtil.isBlank(key) || StringUtil.isBlank(value)){
return false;
}
Jedis jedis =null;
try{
jedis= getJedis();//从jedisPool连接池获取连接的,自己找,这里不写了
Object res= jedis.eval(luascript,Collections.singletonList(key),Collections.singletonList(value));
if(res ==null || "0".equals(res)){
System.out.print("Warnning!!! lock undelete !!!")
}else{
System.out.print("Congrational !!! lock deleted")
}
}catch(Exception e){
return false;
}finally{
jedis.close();
}
return true;
}
}
大概就这样,调用的地方如下
public static viod main(){
String key="key1";
String value="value1";
try{
if(RedisUtil.noLock(key,value)){
if(RedisUtil.lock(key,value)){
//加锁成功。。。
}else{
//加锁失败。。。
}
}else{
//参数不对,这里忽略
}
}catch(Exception e){
//TODO
}finally{
RedisUtil.deleteLock(key,value);
}
}
大概结构就这样,
有人问,为啥要那个nolock方法,这个就是防止万一的,可以加一点其他校验,类似,value值控制,
打个比方,如果,value是时间戳,然后多个对象来抢锁,可以判断,已存在的锁值(时间戳)是不是比来抢的锁值(时间戳)大,
意思就是,A B C先后来抢锁,A 的时间最小,B 的时间中间,C 的最大
B抢到了锁,那么A的时间小,可以不执行了啊(业务判断,如果操作的东西反正取最新的,那就可以不执行了啊)
C后续可以执行,就这么个意思,自己琢磨吧
两个注意点:
加锁时 jedis.set(key,value,"nx","px",TIME_OUT),这个需要注意
解锁时要使用lua脚本,不能乱搞 " if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end "
不了解的看下面的大佬解释的