diff --git a/redisson/src/main/java/org/redisson/RedissonReadLock.java b/redisson/src/main/java/org/redisson/RedissonReadLock.java index 096a335ac..a16d1ad25 100644 --- a/redisson/src/main/java/org/redisson/RedissonReadLock.java +++ b/redisson/src/main/java/org/redisson/RedissonReadLock.java @@ -87,6 +87,8 @@ public class RedissonReadLock extends RedissonLock implements RLock { @Override protected RFuture unlockInnerAsync(long threadId) { String timeoutPrefix = getReadWriteTimeoutNamePrefix(threadId); + String keyPrefix = timeoutPrefix.split(":" + getLockName(threadId))[0]; + return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, "local mode = redis.call('hget', KEYS[1], 'mode'); " + "if (mode == false) then " + @@ -129,7 +131,7 @@ public class RedissonReadLock extends RedissonLock implements RLock { "redis.call('del', KEYS[1]); " + "redis.call('publish', KEYS[2], ARGV[1]); " + "return 1; ", - Arrays.asList(getName(), getChannelName(), timeoutPrefix, timeoutPrefix.split(":")[0]), + Arrays.asList(getName(), getChannelName(), timeoutPrefix, keyPrefix), LockPubSub.unlockMessage, getLockName(threadId)); } diff --git a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java index ca411e5b6..dab811af0 100644 --- a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java +++ b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java @@ -1,10 +1,20 @@ package org.redisson; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.awaitility.Awaitility.await; import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -18,10 +28,38 @@ import org.redisson.api.RReadWriteLock; import org.redisson.api.RedissonClient; import org.redisson.config.Config; -import static org.awaitility.Awaitility.*; - public class RedissonReadWriteLockTest extends BaseConcurrentTest { + @Test + public void testName() throws InterruptedException, ExecutionException, TimeoutException { + ExecutorService service = Executors.newFixedThreadPool(10); + RReadWriteLock rwlock = redisson.getReadWriteLock("{test}:abc:key"); + RLock rlock = rwlock.readLock(); + + List> callables = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + callables.add(() -> { + for (int j = 0; j < 10; j++) { + rlock.lock(); + try { + } finally { + rlock.unlock(); + } + } + return null; + }); + } + + List> futures = service.invokeAll(callables); + for (Future future : futures) { + assertThatCode(future::get).doesNotThrowAnyException(); + } + + service.shutdown(); + assertThat(service.awaitTermination(1, TimeUnit.MINUTES)).isTrue(); + } + + @Test public void testWriteLockExpiration() throws InterruptedException { RReadWriteLock rw1 = redisson.getReadWriteLock("test2s3");