diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
index 652cec84a1..19d4046c92 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
@@ -1,11 +1,12 @@
package me.chanjar.weixin.common.redis;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.util.locks.RedisTemplateSimpleDistributedLock;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
@RequiredArgsConstructor
public class RedisTemplateWxRedisOps implements WxRedisOps {
@@ -37,7 +38,7 @@ public void expire(String key, int expire, TimeUnit timeUnit) {
}
@Override
- public Lock getLock(String key) {
- return new ReentrantLock();
+ public Lock getLock(@NonNull String key) {
+ return new RedisTemplateSimpleDistributedLock(redisTemplate, key, 60 * 1000);
}
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/locks/RedisTemplateSimpleDistributedLock.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/locks/RedisTemplateSimpleDistributedLock.java
new file mode 100644
index 0000000000..dfac1c28fb
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/locks/RedisTemplateSimpleDistributedLock.java
@@ -0,0 +1,126 @@
+package me.chanjar.weixin.common.util.locks;
+
+import lombok.Getter;
+import lombok.NonNull;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisStringCommands;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.data.redis.core.types.Expiration;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * 实现简单的redis分布式锁, 支持重入, 不是红锁
+ *
+ * @see reids distlock
+ */
+public class RedisTemplateSimpleDistributedLock implements Lock {
+
+ @Getter
+ private final StringRedisTemplate redisTemplate;
+ @Getter
+ private final String key;
+ @Getter
+ private final int leaseMilliseconds;
+
+ private final ThreadLocal valueThreadLocal = new ThreadLocal<>();
+
+ public RedisTemplateSimpleDistributedLock(@NonNull StringRedisTemplate redisTemplate, int leaseMilliseconds) {
+ this(redisTemplate, "lock:" + UUID.randomUUID().toString(), leaseMilliseconds);
+ }
+
+ public RedisTemplateSimpleDistributedLock(@NonNull StringRedisTemplate redisTemplate, @NonNull String key, int leaseMilliseconds) {
+ if (leaseMilliseconds <= 0) {
+ throw new IllegalArgumentException("Parameter 'leaseMilliseconds' must grate then 0: " + leaseMilliseconds);
+ }
+ this.redisTemplate = redisTemplate;
+ this.key = key;
+ this.leaseMilliseconds = leaseMilliseconds;
+ }
+
+ @Override
+ public void lock() {
+ while (!tryLock()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+ @Override
+ public void lockInterruptibly() throws InterruptedException {
+ while (!tryLock()) {
+ Thread.sleep(1000);
+ }
+ }
+
+ @Override
+ public boolean tryLock() {
+ String value = valueThreadLocal.get();
+ if (value == null || value.length() == 0) {
+ value = UUID.randomUUID().toString();
+ valueThreadLocal.set(value);
+ }
+ final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
+ final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
+ List