From 222563b376e252fc2036cb717b251be802fa401f Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 29 Jun 2016 10:37:57 +0300 Subject: [PATCH] refactoring --- .../org/redisson/core/RedissonMultiLock.java | 21 +++++--- .../org/redisson/core/RedissonRedLock.java | 3 +- .../org/redisson/RedissonRedLockTest.java | 48 ++++++++++++++++++- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/redisson/core/RedissonMultiLock.java b/src/main/java/org/redisson/core/RedissonMultiLock.java index c66d86564..1b6aca7bf 100644 --- a/src/main/java/org/redisson/core/RedissonMultiLock.java +++ b/src/main/java/org/redisson/core/RedissonMultiLock.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -196,18 +197,26 @@ public class RedissonMultiLock implements Lock { } protected boolean sync(Map> tryLockFutures) { - for (Future future : tryLockFutures.values()) { + List lockedLocks = new ArrayList(tryLockFutures.size()); + RuntimeException latestException = null; + for (Entry> entry : tryLockFutures.entrySet()) { try { - if (!future.syncUninterruptibly().getNow()) { - unlockInner(tryLockFutures.keySet()); - return false; + if (entry.getValue().syncUninterruptibly().getNow()) { + lockedLocks.add(entry.getKey()); } } catch (RuntimeException e) { - unlockInner(tryLockFutures.keySet()); - throw e; + latestException = e; } } + if (lockedLocks.size() < tryLockFutures.size()) { + unlockInner(lockedLocks); + if (latestException != null) { + throw latestException; + } + return false; + } + return true; } diff --git a/src/main/java/org/redisson/core/RedissonRedLock.java b/src/main/java/org/redisson/core/RedissonRedLock.java index c96a84914..3abd1df57 100644 --- a/src/main/java/org/redisson/core/RedissonRedLock.java +++ b/src/main/java/org/redisson/core/RedissonRedLock.java @@ -47,7 +47,7 @@ public class RedissonRedLock extends RedissonMultiLock { } protected boolean sync(Map> tryLockFutures) { - Queue lockedLocks = new ConcurrentLinkedQueue(); + List lockedLocks = new ArrayList(tryLockFutures.size()); RuntimeException latestException = null; for (Entry> entry : tryLockFutures.entrySet()) { try { @@ -61,7 +61,6 @@ public class RedissonRedLock extends RedissonMultiLock { if (lockedLocks.size() < minLocksAmount(locks)) { unlockInner(lockedLocks); - lockedLocks.clear(); if (latestException != null) { throw latestException; } diff --git a/src/test/java/org/redisson/RedissonRedLockTest.java b/src/test/java/org/redisson/RedissonRedLockTest.java index 459f9dc12..5fe975077 100644 --- a/src/test/java/org/redisson/RedissonRedLockTest.java +++ b/src/test/java/org/redisson/RedissonRedLockTest.java @@ -4,12 +4,14 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Assert; import org.junit.Test; import org.redisson.core.RLock; import org.redisson.core.RedissonMultiLock; import org.redisson.core.RedissonRedLock; import io.netty.channel.nio.NioEventLoopGroup; + import org.redisson.RedisRunner.RedisProcess; import static com.jayway.awaitility.Awaitility.await; import static org.assertj.core.api.Assertions.assertThat; @@ -30,6 +32,7 @@ public class RedissonRedLockTest { Thread t1 = new Thread() { public void run() { + lock2.lock(); lock3.lock(); }; }; @@ -41,7 +44,49 @@ public class RedissonRedLockTest { RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3); lock.lock(); - System.out.println("123"); + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + } + + lock.unlock(); + }; + }; + t.start(); + t.join(1000); + + RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3); + Assert.assertFalse(lock.tryLock()); + + assertThat(redis1.stop()).isEqualTo(0); + assertThat(redis2.stop()).isEqualTo(0); + } + + + @Test + public void testLockSuccess() throws IOException, InterruptedException { + RedisProcess redis1 = redisTestMultilockInstance(6320); + RedisProcess redis2 = redisTestMultilockInstance(6321); + + RedissonClient client1 = createClient("127.0.0.1:6320"); + RedissonClient client2 = createClient("127.0.0.1:6321"); + + RLock lock1 = client1.getLock("lock1"); + RLock lock2 = client1.getLock("lock2"); + RLock lock3 = client2.getLock("lock3"); + + Thread t1 = new Thread() { + public void run() { + lock3.lock(); + }; + }; + t1.start(); + t1.join(); + + Thread t = new Thread() { + public void run() { + RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3); + lock.lock(); try { Thread.sleep(3000); @@ -56,7 +101,6 @@ public class RedissonRedLockTest { RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3); lock.lock(); - System.out.println("1234"); lock.unlock(); assertThat(redis1.stop()).isEqualTo(0);