release branch 0.0.4
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>0.0.3</version>
|
||||
<version>0.0.4</version>
|
||||
</parent>
|
||||
<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
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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.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.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.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;
|
||||
|
||||
@@ -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.lock.redis.exception.LockRuntimeException;
|
||||
import com.github.houbb.lock.core.exception.LockRuntimeException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
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.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.LogFactory;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
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.IReadWriteLock;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.houbb.lock.redis.exception;
|
||||
package com.github.houbb.lock.core.exception;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
Reference in New Issue
Block a user