From 3a8c68a19da196f46b72c250ad09770fa104f386 Mon Sep 17 00:00:00 2001 From: "binbin.hou" Date: Thu, 10 Sep 2020 11:19:54 +0800 Subject: [PATCH] [Feature] add for new --- .../com/github/houbb/lock/api/core/ILock.java | 29 +++++++ {lock-redis => lock-core}/pom.xml | 14 +++ .../houbb/lock/redis/bs/LockRedisBs.java | 71 +++++++++++++++ .../lock/redis/constant/LockRedisConst.java | 8 +- .../lock/redis/core/AbstractLockRedis.java | 87 +++++++++++++++++++ .../houbb/lock/redis/core/LockRedis.java | 60 +++++++++++++ .../redis/exception/LockRedisException.java | 27 ++++++ .../github/houbb/lock/redis/package-info.java | 0 .../redis/support/operator/IOperator.java | 9 +- .../support/operator}/impl/JedisOperator.java | 8 +- .../lock/redis/support/package-info.java | 0 .../houbb/lock/redis/bs/LockRedisBs.java | 9 -- .../lock/redis/core/AbstractLockRedis.java | 44 ---------- .../houbb/lock/redis/core/LockRedis.java | 43 --------- .../houbb/lock/redis/support/id/IId.java | 15 ---- .../lock/redis/support/id/impl/IdUUID.java | 23 ----- pom.xml | 16 +++- 17 files changed, 318 insertions(+), 145 deletions(-) rename {lock-redis => lock-core}/pom.xml (67%) create mode 100644 lock-core/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java rename {lock-redis => lock-core}/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java (81%) create mode 100644 lock-core/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java create mode 100644 lock-core/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java create mode 100644 lock-core/src/main/java/com/github/houbb/lock/redis/exception/LockRedisException.java rename {lock-redis => lock-core}/src/main/java/com/github/houbb/lock/redis/package-info.java (100%) rename lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/IRedisOperator.java => lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/IOperator.java (69%) rename {lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis => lock-core/src/main/java/com/github/houbb/lock/redis/support/operator}/impl/JedisOperator.java (86%) rename {lock-redis => lock-core}/src/main/java/com/github/houbb/lock/redis/support/package-info.java (100%) delete mode 100644 lock-redis/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java delete mode 100644 lock-redis/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java delete mode 100644 lock-redis/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java delete mode 100644 lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/IId.java delete mode 100644 lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/impl/IdUUID.java diff --git a/lock-api/src/main/java/com/github/houbb/lock/api/core/ILock.java b/lock-api/src/main/java/com/github/houbb/lock/api/core/ILock.java index e1c9bd9..e19939c 100644 --- a/lock-api/src/main/java/com/github/houbb/lock/api/core/ILock.java +++ b/lock-api/src/main/java/com/github/houbb/lock/api/core/ILock.java @@ -1,5 +1,6 @@ package com.github.houbb.lock.api.core; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; /** @@ -8,4 +9,32 @@ import java.util.concurrent.locks.Lock; * @since 0.0.1 */ public interface ILock extends Lock { + + /** + * 尝试加锁 + * @param time 时间 + * @param unit 当为 + * @param key key + * @return 返回 + * @throws InterruptedException 异常 + * @since 0.0.1 + */ + boolean tryLock(long time, TimeUnit unit, + String key) throws InterruptedException; + + /** + * 尝试加锁 + * @param key key + * @return 返回 + * @since 0.0.1 + */ + boolean tryLock(String key); + + /** + * 解锁 + * @param key key + * @since 0.0.1 + */ + void unlock(String key); + } diff --git a/lock-redis/pom.xml b/lock-core/pom.xml similarity index 67% rename from lock-redis/pom.xml rename to lock-core/pom.xml index 4505218..5840a21 100644 --- a/lock-redis/pom.xml +++ b/lock-core/pom.xml @@ -19,6 +19,20 @@ lock-api + + + com.github.houbb + id-core + + + com.github.houbb + wait + + + com.github.houbb + heaven + + redis.clients diff --git a/lock-core/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java b/lock-core/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java new file mode 100644 index 0000000..a9cbb16 --- /dev/null +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java @@ -0,0 +1,71 @@ +package com.github.houbb.lock.redis.bs; + +import com.github.houbb.id.api.Id; +import com.github.houbb.id.core.core.Ids; +import com.github.houbb.lock.api.core.ILock; +import com.github.houbb.lock.redis.core.LockRedis; +import com.github.houbb.lock.redis.support.operator.IOperator; +import com.github.houbb.wait.api.IWait; +import com.github.houbb.wait.core.Waits; + +/** + * 引导类 + * @author binbin.hou + * @since 0.0.1 + */ +public final class LockRedisBs { + + private LockRedisBs(){} + + /** + * 等待实现 + * @since 0.0.1 + */ + private IWait wait = Waits.threadSleep(); + + /** + * 等待实现 + * @since 0.0.1 + */ + private Id id = Ids.uuid32(); + + /** + * 操作类 + * @since 0.0.1 + */ + private IOperator operator; + + /** + * 新建对象实例 + * @return 对象实例 + * @since 0.0.1 + */ + public static LockRedisBs newInstance() { + return new LockRedisBs(); + } + + public LockRedisBs wait(IWait wait) { + this.wait = wait; + return this; + } + + public LockRedisBs id(Id id) { + this.id = id; + return this; + } + + public LockRedisBs operator(IOperator operator) { + this.operator = operator; + return this; + } + + /** + * 创建锁 + * @return 锁 + * @since 0.0.1 + */ + public ILock lock() { + return new LockRedis(wait, operator, id); + } + +} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java b/lock-core/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java similarity index 81% rename from lock-redis/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java rename to lock-core/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java index 0df4a82..7409054 100644 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/constant/LockRedisConst.java @@ -45,6 +45,12 @@ public final class LockRedisConst { * 暂时定为 30min * @since 0.0.1 */ - public static final long DEFAULT_EXPIRE_MILLS = 1000 * 60 * 30L; + public static final int DEFAULT_EXPIRE_MILLS = 1000 * 60 * 30; + + /** + * 默认锁为全局锁 + * @since 0.0.1 + */ + public static final String DEFAULT_KEY = "GLOBAL"; } diff --git a/lock-core/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java b/lock-core/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java new file mode 100644 index 0000000..e6c64ee --- /dev/null +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java @@ -0,0 +1,87 @@ +package com.github.houbb.lock.redis.core; + +import com.github.houbb.lock.api.core.ILock; +import com.github.houbb.lock.redis.constant.LockRedisConst; +import com.github.houbb.wait.api.IWait; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; + +/** + * 抽象实现 + * @author binbin.hou + * @since 0.0.1 + */ +public abstract class AbstractLockRedis implements ILock { + + /** + * 锁等待 + * @since 0.0.1 + */ + private final IWait wait; + + protected AbstractLockRedis(IWait wait) { + this.wait = wait; + } + + @Override + public void lock() { + throw new UnsupportedOperationException(); + } + + @Override + public void lockInterruptibly() throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean tryLock() { + return tryLock(LockRedisConst.DEFAULT_KEY); + } + + @Override + public void unlock() { + unlock(LockRedisConst.DEFAULT_KEY); + } + + @Override + public boolean tryLock(long time, TimeUnit unit, String key) throws InterruptedException { + long startTimeMills = System.currentTimeMillis(); + + // 一次获取,直接成功 + boolean result = this.tryLock(key); + if(result) { + return true; + } + + // 时间判断 + if(time <= 0) { + return false; + } + long durationMills = unit.toMillis(time); + long endMills = startTimeMills + durationMills; + + // 循环等待 + while (System.currentTimeMillis() < endMills) { + result = tryLock(key); + if(result) { + return true; + } + + // 等待 10ms + wait.wait(TimeUnit.MILLISECONDS, 10); + } + return false; + } + + @Override + public synchronized boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + return tryLock(time, unit, LockRedisConst.DEFAULT_KEY); + } + + @Override + public Condition newCondition() { + throw new UnsupportedOperationException(); + } + +} diff --git a/lock-core/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java b/lock-core/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java new file mode 100644 index 0000000..af2e129 --- /dev/null +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java @@ -0,0 +1,60 @@ +package com.github.houbb.lock.redis.core; + +import com.github.houbb.heaven.util.lang.StringUtil; +import com.github.houbb.id.api.Id; +import com.github.houbb.id.core.util.IdThreadLocalHelper; +import com.github.houbb.lock.redis.constant.LockRedisConst; +import com.github.houbb.lock.redis.exception.LockRedisException; +import com.github.houbb.lock.redis.support.operator.IOperator; +import com.github.houbb.wait.api.IWait; + +/** + * 这里是基于 redis 实现 + * + * 实际上也可以基于 zk/数据库等实现。 + * + * @author binbin.hou + * @since 0.0.1 + */ +public class LockRedis extends AbstractLockRedis { + + /** + * redis 操作实现 + * @since 0.0.1 + */ + private final IOperator redisOperator; + + /** + * 主键标识 + * @since 0.0.1 + */ + private final Id id; + + public LockRedis(IWait wait, IOperator redisOperator, Id id) { + super(wait); + this.redisOperator = redisOperator; + this.id = id; + } + + @Override + public boolean tryLock(String key) { + final String requestId = id.id(); + IdThreadLocalHelper.put(requestId); + + return redisOperator.lock(key, requestId, LockRedisConst.DEFAULT_EXPIRE_MILLS); + } + + @Override + public void unlock(String key) { + final String requestId = IdThreadLocalHelper.get(); + if(StringUtil.isEmpty(requestId)) { + String threadName = Thread.currentThread().getName(); + throw new LockRedisException("Thread " + threadName +" not contains requestId"); + } + + boolean unlock = redisOperator.unlock(key, requestId); + if(!unlock) { + throw new LockRedisException("Unlock key " + key + " result is failed!"); + } + } +} \ No newline at end of file diff --git a/lock-core/src/main/java/com/github/houbb/lock/redis/exception/LockRedisException.java b/lock-core/src/main/java/com/github/houbb/lock/redis/exception/LockRedisException.java new file mode 100644 index 0000000..82d32ca --- /dev/null +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/exception/LockRedisException.java @@ -0,0 +1,27 @@ +package com.github.houbb.lock.redis.exception; + +/** + * @author binbin.hou + * @since 0.0.1 + */ +public class LockRedisException extends RuntimeException { + + public LockRedisException() { + } + + public LockRedisException(String message) { + super(message); + } + + public LockRedisException(String message, Throwable cause) { + super(message, cause); + } + + public LockRedisException(Throwable cause) { + super(cause); + } + + public LockRedisException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/package-info.java b/lock-core/src/main/java/com/github/houbb/lock/redis/package-info.java similarity index 100% rename from lock-redis/src/main/java/com/github/houbb/lock/redis/package-info.java rename to lock-core/src/main/java/com/github/houbb/lock/redis/package-info.java diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/IRedisOperator.java b/lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/IOperator.java similarity index 69% rename from lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/IRedisOperator.java rename to lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/IOperator.java index b28d528..647287c 100644 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/IRedisOperator.java +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/IOperator.java @@ -1,11 +1,11 @@ -package com.github.houbb.lock.redis.support.redis; +package com.github.houbb.lock.redis.support.operator; /** * Redis 客户端 * @author binbin.hou - * @since 1.0.0 + * @since 0.0.1 */ -public interface IRedisOperator { +public interface IOperator { /** * 尝试获取分布式锁 @@ -14,8 +14,9 @@ public interface IRedisOperator { * @param requestId 请求标识 * @param expireTimeMills 超期时间 * @return 是否获取成功 + * @since 0.0.1 */ - boolean tryLock(String lockKey, String requestId, int expireTimeMills); + boolean lock(String lockKey, String requestId, int expireTimeMills); /** * 解锁 diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/impl/JedisOperator.java b/lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/impl/JedisOperator.java similarity index 86% rename from lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/impl/JedisOperator.java rename to lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/impl/JedisOperator.java index d409093..c773b7a 100644 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/redis/impl/JedisOperator.java +++ b/lock-core/src/main/java/com/github/houbb/lock/redis/support/operator/impl/JedisOperator.java @@ -1,7 +1,7 @@ -package com.github.houbb.lock.redis.support.redis.impl; +package com.github.houbb.lock.redis.support.operator.impl; import com.github.houbb.lock.redis.constant.LockRedisConst; -import com.github.houbb.lock.redis.support.redis.IRedisOperator; +import com.github.houbb.lock.redis.support.operator.IOperator; import redis.clients.jedis.Jedis; import java.util.Collections; @@ -11,7 +11,7 @@ import java.util.Collections; * @author binbin.hou * @since 0.0.1 */ -public class JedisOperator implements IRedisOperator { +public class JedisOperator implements IOperator { /** * jedis 客户端 @@ -37,7 +37,7 @@ public class JedisOperator implements IRedisOperator { * @since 0.0.1 */ @Override - public boolean tryLock(String lockKey, String requestId, int expireTimeMills) { + public boolean lock(String lockKey, String requestId, int expireTimeMills) { String result = jedis.set(lockKey, requestId, LockRedisConst.SET_IF_NOT_EXIST, LockRedisConst.SET_WITH_EXPIRE_TIME, expireTimeMills); return LockRedisConst.LOCK_SUCCESS.equals(result); } diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/package-info.java b/lock-core/src/main/java/com/github/houbb/lock/redis/support/package-info.java similarity index 100% rename from lock-redis/src/main/java/com/github/houbb/lock/redis/support/package-info.java rename to lock-core/src/main/java/com/github/houbb/lock/redis/support/package-info.java diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java b/lock-redis/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java deleted file mode 100644 index b0aa2ad..0000000 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/bs/LockRedisBs.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.houbb.lock.redis.bs; - -/** - * 引导类 - * @author binbin.hou - * @since 1.0.0 - */ -public class LockRedisBs { -} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java b/lock-redis/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java deleted file mode 100644 index b76ab40..0000000 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/core/AbstractLockRedis.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.houbb.lock.redis.core; - -import com.github.houbb.lock.api.core.ILock; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; - -/** - * 抽象实现 - * @author binbin.hou - * @since 0.0.1 - */ -public class AbstractLockRedis implements ILock { - - @Override - public void lock() { - throw new UnsupportedOperationException(); - } - - @Override - public void lockInterruptibly() throws InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public boolean tryLock() { - return false; - } - - @Override - public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { - return false; - } - - @Override - public void unlock() { - - } - - @Override - public Condition newCondition() { - throw new UnsupportedOperationException(); - } -} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java b/lock-redis/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java deleted file mode 100644 index e2f6d47..0000000 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/core/LockRedis.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.houbb.lock.redis.core; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; - -/** - * @author binbin.hou - * @since 1.0.0 - */ -public class LockRedis extends AbstractLockRedis { - - @Override - public void lock() { - - } - - @Override - public void lockInterruptibly() throws InterruptedException { - - } - - @Override - public boolean tryLock() { - return false; - } - - @Override - public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { - final long timeMills = unit.toMillis(time); - - return false; - } - - @Override - public void unlock() { - - } - - @Override - public Condition newCondition() { - return null; - } -} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/IId.java b/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/IId.java deleted file mode 100644 index 667a559..0000000 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/IId.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.houbb.lock.redis.support.id; - -/** - * @author binbin.hou - * @since 1.0.0 - */ -public interface IId { - - /** - * 返回唯一标识 - * @return 唯一标识 - */ - String id(); - -} diff --git a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/impl/IdUUID.java b/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/impl/IdUUID.java deleted file mode 100644 index 2b2ea73..0000000 --- a/lock-redis/src/main/java/com/github/houbb/lock/redis/support/id/impl/IdUUID.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.houbb.lock.redis.support.id.impl; - -import com.github.houbb.lock.redis.support.id.IId; - -import java.util.UUID; - -/** - * @author binbin.hou - * @since 1.0.0 - */ -public class IdUUID implements IId { - - /** - * 返回唯一标识 - * - * @return 唯一标识 - */ - @Override - public String id() { - return UUID.randomUUID().toString().replace("-",""); - } - -} diff --git a/pom.xml b/pom.xml index 22b19fe..9822b50 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT lock-api - lock-redis + lock-core @@ -32,7 +32,9 @@ 1.0.6 - 0.1.113 + 0.1.114 + 0.0.6 + 0.0.1 4.12 @@ -59,6 +61,16 @@ heaven ${heaven.version} + + com.github.houbb + id-core + ${id.version} + + + com.github.houbb + wait + ${wait.version} +