release branch 0.0.4
This commit is contained in:
@@ -26,3 +26,9 @@
|
|||||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|:---|:---|:---|:---|:--|
|
|:---|:---|:---|:---|:--|
|
||||||
| 1 | A | redis 锁独立,便于使用 | 2021-12-08 14:45:40 | |
|
| 1 | A | redis 锁独立,便于使用 | 2021-12-08 14:45:40 | |
|
||||||
|
|
||||||
|
# release_0.0.4
|
||||||
|
|
||||||
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|
|:---|:---|:---|:---|:--|
|
||||||
|
| 1 | A | 简单锁的实现,优化 redisLock 实现策略 | 2022-04-17 14:45:40 | |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
# 变更日志
|
# 变更日志
|
||||||
|
|
||||||
> [变更日志](doc/CHANGELOG.md)
|
> [变更日志](CHANGELOG.md)
|
||||||
|
|
||||||
# 快速开始
|
# 快速开始
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ maven 3.x+
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock-core</artifactId>
|
<artifactId>lock-core</artifactId>
|
||||||
<version>${最新版本}</version>
|
<version>0.0.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ Jedis jedis = new Jedis("127.0.0.1", 6379);
|
|||||||
IOperator operator = new JedisOperator(jedis);
|
IOperator operator = new JedisOperator(jedis);
|
||||||
|
|
||||||
// 获取锁
|
// 获取锁
|
||||||
ILock lock = LockRedisBs.newInstance().operator(operator).lock();
|
ILock lock = LockBs.newInstance(operator).lock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean lockResult = lock.tryLock();
|
boolean lockResult = lock.tryLock();
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>lock-api</artifactId>
|
<artifactId>lock-api</artifactId>
|
||||||
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -30,4 +30,12 @@ public interface IOperator {
|
|||||||
*/
|
*/
|
||||||
boolean unlock(String lockKey, String requestId);
|
boolean unlock(String lockKey, String requestId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空过期的锁
|
||||||
|
*
|
||||||
|
* 避免单个线程 unlock 失败,定时移除过期的锁。
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
void clearExpireLock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.github.houbb.lock.core.bs;
|
||||||
|
|
||||||
|
import com.github.houbb.heaven.util.common.ArgUtil;
|
||||||
|
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.api.support.IOperator;
|
||||||
|
import com.github.houbb.lock.core.support.simple.SimpleLock;
|
||||||
|
import com.github.houbb.wait.api.IWait;
|
||||||
|
import com.github.houbb.wait.core.Waits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁引导类
|
||||||
|
*
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
public final class LockBs {
|
||||||
|
|
||||||
|
private LockBs(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空初始化延迟时间
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private long clearInitDelaySeconds = 60;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空初始化周期
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private long clearPeriodSeconds = 60;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用清空任务
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private boolean enableClearTask = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁等待
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
protected IWait waits = Waits.threadSleep();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标识策略
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
protected Id id = Ids.uuid32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作策略
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
protected IOperator operator;
|
||||||
|
|
||||||
|
public static LockBs newInstance(final IOperator operator) {
|
||||||
|
return new LockBs().operator(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs clearInitDelaySeconds(long clearInitDelaySeconds) {
|
||||||
|
this.clearInitDelaySeconds = clearInitDelaySeconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs clearPeriodSeconds(long clearPeriodSeconds) {
|
||||||
|
this.clearPeriodSeconds = clearPeriodSeconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs enableClearTask(boolean enableClearTask) {
|
||||||
|
this.enableClearTask = enableClearTask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs waits(IWait waits) {
|
||||||
|
ArgUtil.notNull(waits, "waits");
|
||||||
|
|
||||||
|
this.waits = waits;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs id(Id id) {
|
||||||
|
ArgUtil.notNull(id, "id");
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBs operator(IOperator operator) {
|
||||||
|
ArgUtil.notNull(operator, "operator");
|
||||||
|
|
||||||
|
this.operator = operator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILock lock() {
|
||||||
|
ArgUtil.notNull(operator, "operator");
|
||||||
|
|
||||||
|
return SimpleLock.newInstance()
|
||||||
|
.waits(waits)
|
||||||
|
.id(id)
|
||||||
|
.operator(operator)
|
||||||
|
.enableClearTask(enableClearTask)
|
||||||
|
.clearInitDelaySeconds(clearInitDelaySeconds)
|
||||||
|
.clearPeriodSeconds(clearPeriodSeconds)
|
||||||
|
.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.constant;
|
package com.github.houbb.lock.core.constant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用锁常量
|
* 通用锁常量
|
||||||
@@ -14,10 +14,10 @@ public final class LockConst {
|
|||||||
/**
|
/**
|
||||||
* 默认的失效时间
|
* 默认的失效时间
|
||||||
*
|
*
|
||||||
* 暂时定为 30min
|
* 暂时定为 1min
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_EXPIRE_MILLS = 1000 * 60 * 30;
|
public static final int DEFAULT_EXPIRE_MILLS = 1000 * 60;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认锁为全局锁
|
* 默认锁为全局锁
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
|
import com.github.houbb.heaven.util.common.ArgUtil;
|
||||||
|
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.api.support.IOperator;
|
||||||
|
import com.github.houbb.lock.core.constant.LockConst;
|
||||||
|
import com.github.houbb.wait.api.IWait;
|
||||||
|
import com.github.houbb.wait.core.Waits;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Condition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象实现
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
public abstract class AbstractLock implements ILock {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁等待
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
protected IWait waits = Waits.threadSleep();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标识策略
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
protected Id id = Ids.uuid32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作策略
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
protected IOperator operator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空初始化延迟时间
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private long clearInitDelaySeconds = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空初始化周期
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private long clearPeriodSeconds = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用清空任务
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
private boolean enableClearTask = true;
|
||||||
|
|
||||||
|
public AbstractLock waits(IWait waits) {
|
||||||
|
this.waits = waits;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLock id(Id id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLock operator(IOperator operator) {
|
||||||
|
this.operator = operator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLock clearInitDelaySeconds(long clearInitDelaySeconds) {
|
||||||
|
this.clearInitDelaySeconds = clearInitDelaySeconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLock clearPeriodSeconds(long clearPeriodSeconds) {
|
||||||
|
this.clearPeriodSeconds = clearPeriodSeconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLock enableClearTask(boolean enableClearTask) {
|
||||||
|
this.enableClearTask = enableClearTask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
public AbstractLock init() {
|
||||||
|
// 参数校验
|
||||||
|
ArgUtil.notNull(operator, "operator");
|
||||||
|
|
||||||
|
// 初始化任务
|
||||||
|
initClearExpireKey();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化清空任务
|
||||||
|
* @since 0.0.6
|
||||||
|
*/
|
||||||
|
private void initClearExpireKey() {
|
||||||
|
if(!enableClearTask) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
//5S 清理一次
|
||||||
|
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
operator.clearExpireLock();
|
||||||
|
}
|
||||||
|
}, clearInitDelaySeconds, clearPeriodSeconds, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lock() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lockInterruptibly() throws InterruptedException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryLock() {
|
||||||
|
return tryLock(LockConst.DEFAULT_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlock() {
|
||||||
|
unlock(LockConst.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待 1ms
|
||||||
|
waits.wait(TimeUnit.MILLISECONDS, 1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
||||||
|
return tryLock(time, unit, LockConst.DEFAULT_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Condition newCondition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.heaven.annotation.ThreadSafe;
|
import com.github.houbb.heaven.annotation.ThreadSafe;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.IReadWriteLock;
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.IReadWriteLock;
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.IReadWriteLock;
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.heaven.util.util.DateUtil;
|
import com.github.houbb.heaven.util.util.DateUtil;
|
||||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.core.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.api.core.IReadWriteLock;
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.houbb.lock.redis.exception;
|
package com.github.houbb.lock.core.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package com.github.houbb.lock.core;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
package com.github.houbb.lock.core.support;
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.github.houbb.lock.core.support.simple;
|
||||||
|
|
||||||
|
import com.github.houbb.heaven.util.lang.StringUtil;
|
||||||
|
import com.github.houbb.id.core.util.IdThreadLocalHelper;
|
||||||
|
import com.github.houbb.lock.core.constant.LockConst;
|
||||||
|
import com.github.houbb.lock.core.core.AbstractLock;
|
||||||
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单锁实现策略
|
||||||
|
*
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
public class SimpleLock extends AbstractLock {
|
||||||
|
|
||||||
|
public static SimpleLock newInstance() {
|
||||||
|
return new SimpleLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryLock(String key) {
|
||||||
|
final String requestId = id.id();
|
||||||
|
IdThreadLocalHelper.put(requestId);
|
||||||
|
|
||||||
|
return operator.lock(key, requestId, LockConst.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 LockRuntimeException("Thread " + threadName +" not contains requestId");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean unlock = operator.unlock(key, requestId);
|
||||||
|
if(!unlock) {
|
||||||
|
throw new LockRuntimeException("Unlock key " + key + " result is failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
|
||||||
import com.github.houbb.lock.redis.constant.LockConst;
|
|
||||||
import com.github.houbb.wait.api.IWait;
|
|
||||||
import com.github.houbb.wait.core.Waits;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 抽象实现
|
|
||||||
* @author binbin.hou
|
|
||||||
* @since 0.0.1
|
|
||||||
*/
|
|
||||||
public abstract class AbstractLock implements ILock {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 锁等待
|
|
||||||
* @since 0.0.1
|
|
||||||
*/
|
|
||||||
private final IWait wait;
|
|
||||||
|
|
||||||
public AbstractLock() {
|
|
||||||
this.wait = Waits.threadSleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AbstractLock(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(LockConst.DEFAULT_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unlock() {
|
|
||||||
unlock(LockConst.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待 1ms
|
|
||||||
wait.wait(TimeUnit.MILLISECONDS, 1);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
|
||||||
return tryLock(time, unit, LockConst.DEFAULT_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Condition newCondition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package com.github.houbb.lock.redis;
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
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.api.support.IOperator;
|
|
||||||
import com.github.houbb.lock.redis.lock.LockRedis;
|
|
||||||
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();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ID 实现
|
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.github.houbb.lock.redis.exception;
|
package com.github.houbb.lock.redis.exception;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.3
|
* @since 0.0.3
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.github.houbb.lock.redis.lock;
|
|
||||||
|
|
||||||
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.api.support.IOperator;
|
|
||||||
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
|
||||||
import com.github.houbb.lock.redis.core.AbstractLock;
|
|
||||||
import com.github.houbb.lock.redis.exception.LockRedisException;
|
|
||||||
import com.github.houbb.wait.api.IWait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 这里是基于 redis 实现
|
|
||||||
*
|
|
||||||
* 实际上也可以基于 zk/数据库等实现。
|
|
||||||
*
|
|
||||||
* @author binbin.hou
|
|
||||||
* @since 0.0.1
|
|
||||||
*/
|
|
||||||
public class LockRedis extends AbstractLock {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
package com.github.houbb.lock.redis;
|
package com.github.houbb.lock.redis;
|
||||||
|
|||||||
@@ -60,4 +60,9 @@ public class JedisOperator implements IOperator {
|
|||||||
return LockRedisConst.RELEASE_SUCCESS.equals(result);
|
return LockRedisConst.RELEASE_SUCCESS.equals(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearExpireLock() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
package com.github.houbb.lock.redis.support;
|
package com.github.houbb.lock.redis.support;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package com.github.houbb.lock.test.core;
|
package com.github.houbb.lock.test.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockSpin;
|
import com.github.houbb.lock.core.core.LockSpinRe;
|
||||||
import com.github.houbb.lock.redis.core.LockSpinRe;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.houbb.lock.test.core;
|
package com.github.houbb.lock.test.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockSpin;
|
import com.github.houbb.lock.core.core.LockSpin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.github.houbb.lock.test.core;
|
|||||||
|
|
||||||
import com.github.houbb.heaven.util.util.DateUtil;
|
import com.github.houbb.heaven.util.util.DateUtil;
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockWaitNotify;
|
import com.github.houbb.lock.core.core.LockWaitNotify;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.github.houbb.lock.test.core;
|
|||||||
|
|
||||||
import com.github.houbb.heaven.util.util.DateUtil;
|
import com.github.houbb.heaven.util.util.DateUtil;
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockWaitNotify;
|
import com.github.houbb.lock.core.core.LockWaitNotify;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
package com.github.houbb.lock.test.core;
|
package com.github.houbb.lock.test.core;
|
||||||
|
|
||||||
import com.github.houbb.heaven.util.util.DateUtil;
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockWaitNotify;
|
import com.github.houbb.lock.core.core.LockWaitNotifyRe;
|
||||||
import com.github.houbb.lock.redis.core.LockWaitNotifyRe;
|
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.github.houbb.lock.test.redis;
|
|||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.api.support.IOperator;
|
import com.github.houbb.lock.api.support.IOperator;
|
||||||
import com.github.houbb.lock.redis.bs.LockRedisBs;
|
import com.github.houbb.lock.core.bs.LockBs;
|
||||||
import com.github.houbb.lock.redis.support.operator.JedisOperator;
|
import com.github.houbb.lock.redis.support.operator.JedisOperator;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -21,7 +21,7 @@ public class LockRedisTest {
|
|||||||
IOperator operator = new JedisOperator(jedis);
|
IOperator operator = new JedisOperator(jedis);
|
||||||
|
|
||||||
// 获取锁
|
// 获取锁
|
||||||
ILock lock = LockRedisBs.newInstance().operator(operator).lock();
|
ILock lock = LockBs.newInstance(operator).lock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean lockResult = lock.tryLock();
|
boolean lockResult = lock.tryLock();
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>lock-api</module>
|
<module>lock-api</module>
|
||||||
<module>lock-core</module>
|
<module>lock-core</module>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<!--============================== INTER ==============================-->
|
<!--============================== INTER ==============================-->
|
||||||
<plugin.gen.version>1.0.6</plugin.gen.version>
|
<plugin.gen.version>1.0.6</plugin.gen.version>
|
||||||
<heaven.version>0.1.148</heaven.version>
|
<heaven.version>0.1.161</heaven.version>
|
||||||
<id.version>0.0.6</id.version>
|
<id.version>0.0.6</id.version>
|
||||||
<wait.version>0.0.1</wait.version>
|
<wait.version>0.0.1</wait.version>
|
||||||
<log-integration.version>1.1.8</log-integration.version>
|
<log-integration.version>1.1.8</log-integration.version>
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ ECHO "============================= RELEASE START..."
|
|||||||
|
|
||||||
:: 版本号信息(需要手动指定)
|
:: 版本号信息(需要手动指定)
|
||||||
:::: 旧版本名称
|
:::: 旧版本名称
|
||||||
SET version=0.0.3
|
SET version=0.0.4
|
||||||
:::: 新版本名称
|
:::: 新版本名称
|
||||||
SET newVersion=0.0.4
|
SET newVersion=0.0.5
|
||||||
:::: 组织名称
|
:::: 组织名称
|
||||||
SET groupName=com.github.houbb
|
SET groupName=com.github.houbb
|
||||||
:::: 项目名称
|
:::: 项目名称
|
||||||
|
|||||||
Reference in New Issue
Block a user