diff --git a/redisson/src/main/java/org/redisson/RedissonReadLock.java b/redisson/src/main/java/org/redisson/RedissonReadLock.java index 8524ab809..36426219a 100644 --- a/redisson/src/main/java/org/redisson/RedissonReadLock.java +++ b/redisson/src/main/java/org/redisson/RedissonReadLock.java @@ -72,7 +72,8 @@ public class RedissonReadLock extends RedissonLock implements RLock { "local key = KEYS[2] .. ':' .. ind;" + "redis.call('set', key, 1); " + "redis.call('pexpire', key, ARGV[1]); " + - "redis.call('pexpire', KEYS[1], ARGV[1]); " + + "local remainTime = redis.call('pttl', KEYS[1]); " + + "redis.call('pexpire', KEYS[1], math.max(remainTime, ARGV[1])); " + "return nil; " + "end;" + "return redis.call('pttl', KEYS[1]);", diff --git a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java index 9d048ffea..c455b8b32 100644 --- a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java +++ b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java @@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +import org.awaitility.Awaitility; import org.awaitility.Duration; import org.junit.Assert; import org.junit.Test; @@ -31,6 +32,48 @@ import org.redisson.config.Config; public class RedissonReadWriteLockTest extends BaseConcurrentTest { + @Test + public void testReadLockExpiration() throws Exception{ + Thread thread1 = new Thread(() -> { + RReadWriteLock rReadWriteLock = redisson.getReadWriteLock("test"); + RLock readLock = rReadWriteLock.readLock(); + readLock.lock(10, TimeUnit.SECONDS); + try { + Thread.sleep(9100); + } catch (Exception e){} + readLock.unlock(); + }); + + + Thread thread2 = new Thread(() -> { + RReadWriteLock rReadWriteLock = redisson.getReadWriteLock("test"); + RLock readLock = rReadWriteLock.readLock(); + readLock.lock(3, TimeUnit.SECONDS); + try { + Thread.sleep(2800); + } catch (Exception e){} + readLock.unlock(); + }); + + AtomicBoolean flag = new AtomicBoolean(); + Thread thread3 = new Thread(() -> { + RReadWriteLock rReadWriteLock = redisson.getReadWriteLock("test"); + RLock writeLock = rReadWriteLock.writeLock(); + writeLock.lock(10, TimeUnit.SECONDS); + flag.set(true); + writeLock.unlock(); + }); + + thread1.start(); + thread1.join(300); + thread2.start(); + thread2.join(300); + thread3.start(); + thread3.join(300); + + Awaitility.await().between(8, TimeUnit.SECONDS, 10, TimeUnit.SECONDS).untilTrue(flag); + } + @Test public void testReadLockExpirationRenewal() throws InterruptedException { int threadCount = 50;