Redis分布式锁实现原理 java版

来源:互联网 发布:去工业化知乎 编辑:程序博客网 时间:2024/04/30 07:23
说明:
Redis因为是单线程的,所以本身没有锁的概念。
所以分布式锁的实现原理是往Redis当中写入一个key(调用方法setnx),写入成功相当于获取锁成功。写入失败也即是setnx方法返回0,获取锁失败。
注意锁的失效时间,否则容易造成死锁。


/**  * 锁在给定的等待时间内空闲,则获取锁成功 返回true, 否则返回false  * @param subKey  * @param timeout 如果timeout=0,取不到锁时,不等待,直接返回.  * @param unit  * @return  */ public boolean tryLock(String subKey, long timeout, TimeUnit unit) {  String key = LOCK_KEY + subKey;  Jedis jedis = null;  try {   jedis = getConnection();   if (jedis == null) {    return Boolean.FALSE;   }   long nano = System.nanoTime();   do {    logger.debug("try lock key: " + key);    Long i = jedis.setnx(key, key);    if (i == 1) {     jedis.expire(key, EXPIRED_TIME);     logger.debug("get lock, key: " + key + " , expire in " + EXPIRED_TIME + " seconds.");     return Boolean.TRUE;    } else { // 存在锁     if (logger.isDebugEnabled()) {      String desc = jedis.get(key);      logger.debug("key: " + key + " locked by another business:" + desc);     }    }    if (timeout == 0) { //取不到锁时,不等待,直接返回.     break;    }    Thread.sleep(200);   } while ((System.nanoTime() - nano) < unit.toNanos(timeout));//取不到锁时等待,直到timeout   return Boolean.FALSE;  } catch (JedisConnectionException je) {   logger.error(je.getMessage(), je);   returnBorkenConnection(jedis);  } catch (Exception e) {   logger.error(e.getMessage(), e);  } finally {   returnConnection(jedis);  }  return Boolean.FALSE; }/**  * 如果锁空闲立即返回   获取失败 一直等待  * @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) {    logger.debug("lock key: " + key);    Long i = jedis.setnx(key, key);    if (i == 1) {     jedis.expire(key, EXPIRED_TIME);     logger.debug("get lock, key: " + key + " , expire in " + EXPIRED_TIME + " seconds.");     isLock = true;    } else {     if (logger.isDebugEnabled()) {      String desc = jedis.get(key);      logger.debug("key: " + key + " locked by another business:" + desc);     }     isLock = false;    }    Thread.sleep(500);   }  } catch (JedisConnectionException je) {   logger.error(je.getMessage(), je);   returnBorkenConnection(jedis);  } catch (Exception e) {   logger.error(e.getMessage(), e);  } finally {   returnConnection(jedis);  }  return isLock; }/**  * 释放锁  * @param subKey  */ public void unLock(String 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);   returnBorkenConnection(jedis);  } catch (Exception e) {   logger.error(e.getMessage(), e);  } finally {   returnConnection(jedis);  } }



0 0
原创粉丝点击