package com.paic.pscp.ejb.ejbmgr.biz.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import com.paic.pscp.manager.common.util.LogRecorder;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisException;
/**
* Redis实现分布式锁
*/
public class RedisLock {
/**
* Logger
*/
private static LogRecorder logUtil = LogRecorder.getInstance();
/**
*
*
* @param lockKey 锁key
* @param expireTime 自动释放锁时间,单位秒
* @param timeout 取锁超时时间,单位毫秒
* @return
*/
public boolean lock(final String lockKey, final int expireTime, final long timeout) {
logUtil.info("RedisLock[{1}]try lock! lockKey="+lockKey+",expireTime"+expireTime+" ,timeout"+timeout);
boolean locked = false;
long now = System.nanoTime();
do {
try {
String value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.format(new Date())
+ "_"
+ Thread.currentThread().getName()
+ "_"
+ UUID.randomUUID().toString();
long lock = JedisUtil.setnx(lockKey, value);
logUtil.info("RedisLock[{2}]Setnx result"+lock+", value:"+value);
locked = (1 == lock);
if (locked) {//首次进入的锁设置过期时间
return JedisUtil.expire(lockKey, expireTime);
} else {
String ctx = JedisUtil.get(lockKey);
Long expire = JedisUtil.ttl(lockKey);
logUtil.info("RedisLock[{3}] Lock key:"+lockKey+", value:"+ctx+", expireTime:"+ expire);
// 如果没有设置超时时间,则设置为当前的超时时间
if(expire == -1) {
JedisUtil.expire(lockKey, expireTime);
}
}
} catch (JedisException e) {
// redis操作异常
logUtil.error(getClass(), "lock()", "[{2}] 操作Redis锁失败 lockkey = {"+lockKey+"}", e, "JedisException");
continue;
} catch (Exception e) {
logUtil.error(getClass(), "lock()", "[{2}] 操作Redis锁失败 lockkey = {"+lockKey+"}", e, "RedisLock");
}
} while (!locked && (System.nanoTime() - now < timeout * 1000));
logUtil.info("RedisLock[{2}] try lock finished! lockKey="+lockKey+", locked={"+locked+"}");
return locked;
}
/**
*
*
* @param lockKey 锁key
* @param timeout 释放锁超时时间, 单位毫秒
* @return
*/
public boolean unLock(final String lockKey, final long timeout) {
logUtil.info("RedisLock[{1}]try lock! lockKey="+lockKey+" ,timeout"+timeout);
long now = System.nanoTime();
do {
try {
long lock = JedisUtil.del(lockKey);
return 1 == lock;
} catch (Exception e) {
// redis操作异常
logUtil.error(this.getClass(),"unLock()","[{1}] 操作Redis锁失败 lockkey = {"+lockKey+"}" ,e,"RedisLock");
continue;
}
} while (System.nanoTime() - now < timeout * 1000);
logUtil.info("RedisLock[{1}] unlock success! lockKey={"+lockKey+"}");
return false;
}
}
redis分布式锁
最新推荐文章于 2025-02-18 14:23:29 发布