package com.ods.common.util;
import java.util.Random;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
public class RedisLockUtil {
/** 加锁标志 */
public static final String LOCKED = "1";
/** 毫秒与毫微秒的换算单位 1毫秒 = 1000000毫微秒 */
public static final long MILLI_NANO_CONVERSION = 1000 * 1000L;
/** 默认超时时间(毫秒) */
public static final long DEFAULT_TIME_OUT = 1000;
public static final Random RANDOM = new Random();
/** 锁的超时时间(秒),过期删除 */
public static final int EXPIRE = 60;
/**
* 加锁
* 应该以:
* lock();
* try {
* doSomething();
* } finally {
* unlock();
* }
* 的方式调用
* @param timeout 超时时间
* @return 成功或失败标志
*/
public static boolean lock(ShardedJedis jedis,String key1,long timeout) {
String key = key1 + "_lock";
long nano = System.nanoTime();
timeout *= MILLI_NANO_CONVERSION;
try {
while ((System.nanoTime() - nano) < timeout) {
if (jedis.setnx(key, LOCKED) == 1) {
jedis.expire(key, EXPIRE);
return true;
}
// 短暂休眠,避免出现活锁
Thread.sleep(3, RANDOM.nextInt(500));
}
} catch (Exception e) {
throw new RuntimeException("Locking error", e);
}
return false;
}
/**
* 加锁
* 应该以:
* lock();
* try {
* doSomething();
* } finally {
* unlock();
* }
* 的方式调用
* @param timeout 超时时间
* @param expire 锁的超时时间(秒),过期删除
* @return 成功或失败标志
*/
public static boolean lock(ShardedJedis jedis,String key1 ,long timeout, int expire) {
String key = key1 + "_lock";
long nano = System.nanoTime();
timeout *= MILLI_NANO_CONVERSION;
try {
while ((System.nanoTime() - nano) < timeout) {
if (jedis.setnx(key, LOCKED) == 1) {
jedis.expire(key, expire);
return true;
}
// 短暂休眠,避免出现活锁
Thread.sleep(3);
}
} catch (Exception e) {
throw new RuntimeException("Locking error", e);
}
return false;
}
/**
* 加锁
* 应该以:
* lock();
* try {
* doSomething();
* } finally {
* unlock();
* }
* 的方式调用
* @return 成功或失败标志
*/
public static boolean lock(ShardedJedis jedis,String key) {
return lock(jedis,key,DEFAULT_TIME_OUT);
}
/**
* 解锁
* 无论是否加锁成功,都需要调用unlock
* 应该以:
* lock();
* try {
* doSomething();
* } finally {
* unlock();
* }
* 的方式调用
*/
public static void unlock(ShardedJedis jedis,String key1) {
String key = key1 + "_lock";
String value=jedis.get(key);
if(StringUtil.equals(LOCKED, value)){
jedis.del(key);
}
}
}