前言:最近在做项目开发的过程中,因为项目框架采用的是分布式框架,涉及到一些分布式锁的问题。空闲时间,把这些代码记录下来,与大家分享。
Redis本身是单线程的,没有锁的概念。所有分布式锁的原理是:往Redis中写入一个Key(调用方法setNX()),写入成功相当于获取锁成功。写入失败也即是setNX()返回0
获取锁失败,注意锁的失效时间,否则容易造成死锁。
Talk is cheap ,show my code
public class RedisLock{
/***锁在给定的空闲时间内空闲,则获取锁成功,返回ture,否则返回false**/
@param subkey
@param timeout 如果timeout等于0,获取不到锁,直接返回
@param unit 时间单位
public boolean tryLock(String subkey,long timeout,TimeUnit unit ){
Jedis jedis=null;
try{
jedis=getConnection();
if(jedis==null){
return Boolean.FALSE;
}
long nano=System.nanoTime();
do{
long i=jedis.setNX(key,key);
if(i==1){
jedis.expire(key,EXPIRE_TIME);
return Boolean.TRUE;
}else{
//锁已经被占了
String desc=jedis.get(key);
logger.debug("key:"+key+"locked by another bussiness:"+desc);
}
if(timeout==0){//取不到锁时,不等待直接返回
break;
}
Thread.sleep(200);
}while((System.nanoTime()-nano)<unit.toNanos(timeout));
return Boolean.FALSE
catch(Exception e){
e.printStackTrace();
}
- /**
- * 如果锁空闲立即返回 获取失败 一直等待
- * @param subKey
- */
public boolean lock(String subKey){
String key=LOCK_KEY+subKey;
Jedis jedis=null;
boolean isLock=false;
try{
jedis=getConnection();
if(jedis==null){
return isLock;
}
while(true){
long i=jedis.setNX(key,key);
if(i==1){
jedis.expire(key,EXPIRE_TIME);
isLock=true;
}else{//存在锁
String desc=jedis.get(key);
logger.debug("key:"+key+"locked bu another business"+desc);
isLock=false;
}
Thread.sleep(500);
}
}catch(Exception e){
e.printStackTrace();
return isLock;
}
return isLock;
}
/*释放锁*/
public void unlock(Sting subKey){
String key = LOCK_KEY + subKey;
Jedis jedis = null;
try {
jedis = getConnection();
if (jedis == null) {
return;
}
jedis.del(key);
logger.debug("release lock, keys :" + key);
} catch (JedisConnectionException je) {
logger.error(je.getMessage(), je);
} catch (Exception e) {
e.printStackTrace();
}
}
}