Redis分散式鎖實現原理 java版
阿新 • • 發佈:2019-02-14
/** * 鎖在給定的等待時間內空閒,則獲取鎖成功 返回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); } }