package com.sys.util;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.plugin.redis.serializer.FstSerializer;
import redis.clients.jedis.Jedis;
import java.util.Collections;
/**
* Created by qyh
*/
public class LockUtils {
/**
* redis分布式锁
* timeoutSecond:轮训获取锁等待时间(秒),0表示不等待锁
* sleepMils:轮训等待,线程sleep时间
* lockTimeSecond:线程设置的锁过期时间,当前时间在此时间之后,其他线程即可获取到锁
* expireSecond:此时间一般要大于lockTimeSecond,作用:expireSecond内没有线程访问,将该key清除redis
*/
public static boolean lock(Cache cache, String key, long timeoutSecond, long lockTimeSecond
, int expireSecond, Long sleepMils) {
boolean lockSuccess = false;
Jedis jedis = cache.getJedis();
try{
long start = System.currentTimeMillis();
byte[] lockKey = FstSerializer.me.keyToBytes(key);
do{
//获取锁
long result = jedis.setnx(lockKey,FstSerializer.me.keyToBytes(String.valueOf(System.currentTimeMillis()+lockTimeSecond*1000)));
if(result == 1){//成功
lockSuccess = true;
//没有del
if (expireSecond != 0){
jedis.expire(lockKey,expireSecond);
}
break;
}else{//失败
//获取锁的超时时间
String lockTimeStr = FstSerializer.me.keyFromBytes(jedis.get(lockKey));
//如果没有获取到锁的超时时间,说明,这个时候,被del或者expire到期,结束,睡眠一段时间,继续获取锁
if(lockTimeStr != null){
long lockTime = Long.valueOf(lockTimeStr);
//如果锁过期
if(lockTime < System.currentTimeMillis()){
//为锁设置新的时间,并返回之前的时间
String originStr = FstSerializer.me.keyFromBytes(jedis.getSet(lockKey,FstSerializer.me.keyToBytes(String.valueOf(System.currentTimeMillis()+ lockTimeSecond*1000))));
//对比之前的时间和返回的时间,相等,说明拿到锁,如果不相等,说明没拿到
if(lockTimeStr.equals(originStr)){
lockSuccess = true;
//没有del
if (expireSecond != 0){
jedis.expire(lockKey,expireSecond);
}
break;
}
}
}
}
if(timeoutSecond == 0){
break;
}
Thread.sleep(sleepMils);
}while((System.currentTimeMillis()-start) < timeoutSecond*1000);
}catch(Exception e){
e.printStackTrace();
}
jedis.close();
return lockSuccess;
}
public static void unlock(Cache cache, String key) {
Jedis jedis = cache.getJedis();
jedis.del(FstSerializer.me.keyToBytes(key));
jedis.close();
}
public static Boolean lock1(String key,String value,Long tiemOut){
Cache cache = Redis.use();
Jedis jedis = cache.getJedis();
String result = jedis.set(key,value,"NX","EX",tiemOut);
if ("OK".equals(result)){
jedis.close();
return true;
}
jedis.close();
return false;
}
private static final Long UNLOCK_SUCCESS = 1L;
public static Boolean unLock1(String key,String value){
Cache cache = Redis.use();
Jedis jedis = cache.getJedis();
String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end";
Object var2 = jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(value));
if (UNLOCK_SUCCESS == var2) {
jedis.close();
return true;
}
jedis.close();
return false;
}
}
redis分布式锁
最新推荐文章于 2021-07-31 09:27:32 发布