|
@@ -0,0 +1,116 @@
|
|
|
+package com.yonge.cooleshow.biz.dal.support;
|
|
|
+
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.concurrent.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 分布式竞争锁
|
|
|
+ *
|
|
|
+ * @author hgw
|
|
|
+ */
|
|
|
+public class DistributedLock {
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(DistributedLock.class);
|
|
|
+
|
|
|
+ private final RedissonClient redissonClient;
|
|
|
+
|
|
|
+ private static final long DEFAULT_TIMEOUT = 60L;// key过期时间默认1分钟后
|
|
|
+
|
|
|
+ private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;//默认过期时间单位-秒钟
|
|
|
+
|
|
|
+ private DistributedLock(RedissonClient redissonClient) {
|
|
|
+ this.redissonClient = redissonClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static DistributedLock of(RedissonClient redissonClient) {
|
|
|
+ return new DistributedLock(redissonClient);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分布式锁-默认锁60秒
|
|
|
+ *
|
|
|
+ * @param lockName lockKey
|
|
|
+ * @param runnable 任务
|
|
|
+ * @return true 锁成功 false 锁失败
|
|
|
+ */
|
|
|
+ public boolean runIfLockCanGet(final String lockName, Runnable runnable) {
|
|
|
+ return runIfLockCanGet(lockName, runnable, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分布式锁
|
|
|
+ *
|
|
|
+ * @param lockName lockKey
|
|
|
+ * @param runnable 任务
|
|
|
+ * @param timeout 超时时间
|
|
|
+ * @param unit 超时时间单位
|
|
|
+ * @return true 锁成功 false 锁失败
|
|
|
+ */
|
|
|
+ public boolean runIfLockCanGet(final String lockName, Runnable runnable, final long timeout, TimeUnit unit) {
|
|
|
+ RLock lock = redissonClient.getLock(lockName);
|
|
|
+ if (Objects.isNull(lock)) {
|
|
|
+ log.info("runIfLockCanGet lock is null lockName : {}", lockName);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ if (lock.tryLock(0, timeout, unit)) {
|
|
|
+ if (Objects.nonNull(runnable)) {
|
|
|
+ runnable.run();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("runIfLockCanGet error lockName : {}", lockName, e);
|
|
|
+ throw new RuntimeException("runIfLockCanGet error lockName :" + lockName, e);
|
|
|
+ } finally {
|
|
|
+ unlock(lock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分布式锁-异步
|
|
|
+ *
|
|
|
+ * @param lockName lockKey
|
|
|
+ * @param callable 任务
|
|
|
+ * @param timeout 超时时间
|
|
|
+ * @param unit 超时时间单位
|
|
|
+ * @return true 锁成功 false 锁失败
|
|
|
+ */
|
|
|
+ public <T> Future<T> callIfLockCanGet(final String lockName, Callable<T> callable, final long timeout, TimeUnit unit) {
|
|
|
+ RLock lock = redissonClient.getLock(lockName);
|
|
|
+ if (Objects.isNull(lock)) {
|
|
|
+ log.info("callIfLockCanGet lock is null lockName : {}", lockName);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ ExecutorService executor = Executors.newCachedThreadPool();
|
|
|
+ try {
|
|
|
+ if (lock.tryLock(0, timeout, unit)) {
|
|
|
+ return executor.submit(callable);
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("callIfLockCanGet error lockKey {}", lockName);
|
|
|
+ throw new RuntimeException("任务执行异常");
|
|
|
+ } finally {
|
|
|
+ executor.shutdown();
|
|
|
+ unlock(lock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解锁
|
|
|
+ */
|
|
|
+ private void unlock(RLock lock) {
|
|
|
+ if (lock.getHoldCount() != 0) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|