Skip to content

Commit

Permalink
⚡ DistributedLock 优化斐波那契数计算 & 锁竞争失败处理应在重试结束后执行
Browse files Browse the repository at this point in the history
  • Loading branch information
Hccake committed Oct 23, 2023
1 parent 0e82a37 commit 3f74e3b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ public Object around(ProceedingJoinPoint point) throws Throwable {
// 失效时间控制
Consumer<Object> cachePut = prodCachePutFunction(valueOperations, key, cachedAnnotation.ttl(),
cachedAnnotation.timeUnit());
int retryCount = cachedAnnotation.retryCount();
return cached(
new CachedOps(point, lockKey, cacheQuery, cachePut, method.getGenericReturnType(), retryCount));
CachedOps ops = new CachedOps(point, lockKey, cacheQuery, cachePut, method.getGenericReturnType(),
cachedAnnotation.retryCount());
return cached(ops);
}

// 缓存更新处理
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.concurrent.TimeUnit;

/**
* 利用Aop, 在方法调用前先查询缓存 若缓存中没有数据,则调用方法本身,并将方法返回值放置入缓存中
*
* @author Hccake
* @version 1.0
* @date 2019/8/31 16:08 利用Aop, 在方法调用前先查询缓存 若缓存中没有数据,则调用方法本身,并将方法返回值放置入缓存中
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
Expand Down Expand Up @@ -36,8 +36,8 @@
TimeUnit timeUnit() default TimeUnit.SECONDS;

/**
* 锁竞争失败时的重试次数 小于0: 无限重试 等于0: 不重试 大于0: 重试次数
* @return
* 锁竞争失败时的重试次数
* @return 负数: 无限重试, 0: 不重试, 正数: 重试次数
*/
int retryCount() default 5;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ public StateHandler<T> retryCount(int retryCount) {
@Override
public T lock() {
String requestId = UUID.randomUUID().toString();
boolean exResolved = false;
if (Boolean.TRUE.equals(CacheLock.lock(this.key, requestId, this.timeout, this.timeUnit))) {

if (Boolean.TRUE.equals(tryLock(requestId))) {
boolean exResolved = false;
T value = null;
try {
value = executeAction.execute();
Expand All @@ -101,33 +102,71 @@ public T lock() {
this.result = this.successAction.apply(value);
}
}
if (lockFailAction != null) {
this.result = lockFailAction.get();
}
int fib = 3;
while (this.result == null && lockFailAction != null && !exResolved && retryCount-- != 0) {
// 使用斐波那契数列进行睡眠时间的增长
ThreadUtil.safeSleep(calculateFibonacci(fib++) * 10);
else if (lockFailAction != null) {
this.result = lockFailAction.get();
}

return this.result;

}

private Boolean tryLock(String requestId) {
Fibonacci fibonacci = new Fibonacci(10);
int tryCount = 0;
while (true) {
tryCount++;

Boolean lockSuccess = CacheLock.lock(this.key, requestId, this.timeout, this.timeUnit);
if (Boolean.TRUE.equals(lockSuccess)) {
return true;
}

if (this.retryCount >= 0 && tryCount > this.retryCount) {
return false;
}

try {
Thread.sleep(fibonacci.next());
}
catch (InterruptedException ignore) {
// do nothing
}
}
}

@SuppressWarnings("unchecked")
private static <E extends Throwable> void throwException(Throwable t) throws E {
throw (E) t;
}

/**
* 计算斐波那契值
* @param fib
* @return
*/
public int calculateFibonacci(int fib) {
if (fib <= 0 || fib == 1 || fib == 2) {
return 1;
static class Fibonacci {

private long current;

private long prev = 0;

private boolean first = true;

public Fibonacci() {
this(1);
}
return calculateFibonacci(fib - 1) + calculateFibonacci(fib - 2);

public Fibonacci(int initial) {
this.current = initial;
}

public long next() {
long next = this.current + this.prev;
if (first) {
first = false;
}
else {
this.prev = this.current;
this.current = next;
}
return next;
}

}

}

0 comments on commit 3f74e3b

Please sign in to comment.