diff --git a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/CacheStringAspect.java b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/CacheStringAspect.java index 79aaa5c17..fdf950025 100644 --- a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/CacheStringAspect.java +++ b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/CacheStringAspect.java @@ -91,9 +91,9 @@ public Object around(ProceedingJoinPoint point) throws Throwable { // 失效时间控制 Consumer 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); } // 缓存更新处理 diff --git a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/annotation/Cached.java b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/annotation/Cached.java index 98da17d8e..9e0b358c1 100644 --- a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/annotation/Cached.java +++ b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/core/annotation/Cached.java @@ -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) @@ -36,8 +36,8 @@ TimeUnit timeUnit() default TimeUnit.SECONDS; /** - * 锁竞争失败时的重试次数 小于0: 无限重试 等于0: 不重试 大于0: 重试次数 - * @return + * 锁竞争失败时的重试次数 + * @return 负数: 无限重试, 0: 不重试, 正数: 重试次数 */ int retryCount() default 5; diff --git a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/lock/DistributedLock.java b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/lock/DistributedLock.java index 00a17011a..f776c2482 100644 --- a/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/lock/DistributedLock.java +++ b/ballcat-common/ballcat-common-redis/src/main/java/com/hccake/ballcat/common/redis/lock/DistributedLock.java @@ -83,8 +83,9 @@ public StateHandler 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(); @@ -101,16 +102,36 @@ 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") @@ -118,16 +139,34 @@ private static 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; + } + } }