package org.redisson; import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Test; import io.netty.channel.nio.NioEventLoopGroup; import org.redisson.RedisRunner.RedisProcess; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import static com.jayway.awaitility.Awaitility.await; import static org.assertj.core.api.Assertions.assertThat; public class RedissonMultiLockTest { @Test public void testMultiThreads() throws IOException, InterruptedException { RedisProcess redis1 = redisTestMultilockInstance(); Config config1 = new Config(); config1.useSingleServer().setAddress(redis1.getRedisServerAddressAndPort()); RedissonClient client = Redisson.create(config1); RLock lock1 = client.getLock("lock1"); RLock lock2 = client.getLock("lock2"); RLock lock3 = client.getLock("lock3"); Thread t = new Thread() { public void run() { RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); lock.lock(); try { Thread.sleep(3000); } catch (InterruptedException e) { } lock.unlock(); }; }; t.start(); t.join(1000); RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); lock.lock(); lock.unlock(); client.shutdown(); assertThat(redis1.stop()).isEqualTo(0); } @Test public void test() throws IOException, InterruptedException { RedisProcess redis1 = redisTestMultilockInstance(); RedisProcess redis2 = redisTestMultilockInstance(); RedisProcess redis3 = redisTestMultilockInstance(); NioEventLoopGroup group = new NioEventLoopGroup(); RedissonClient client1 = createClient(group, redis1.getRedisServerAddressAndPort()); RedissonClient client2 = createClient(group, redis2.getRedisServerAddressAndPort()); RedissonClient client3 = createClient(group, redis3.getRedisServerAddressAndPort()); final RLock lock1 = client1.getLock("lock1"); final RLock lock2 = client2.getLock("lock2"); final RLock lock3 = client3.getLock("lock3"); RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); lock.lock(); final AtomicBoolean executed = new AtomicBoolean(); Thread t = new Thread() { @Override public void run() { RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); assertThat(lock.tryLock()).isFalse(); assertThat(lock.tryLock()).isFalse(); executed.set(true); } }; t.start(); t.join(); await().atMost(5, TimeUnit.SECONDS).until(() -> assertThat(executed.get()).isTrue()); lock.unlock(); client1.shutdown(); client2.shutdown(); client3.shutdown(); assertThat(redis1.stop()).isEqualTo(0); assertThat(redis2.stop()).isEqualTo(0); assertThat(redis3.stop()).isEqualTo(0); } private RedissonClient createClient(String host) { return createClient(null, host); } private RedissonClient createClient(NioEventLoopGroup group, String host) { Config config1 = new Config(); config1.useSingleServer().setAddress(host); config1.setEventLoopGroup(group); RedissonClient client1 = Redisson.create(config1); client1.getKeys().flushdb(); return client1; } private RedisProcess redisTestMultilockInstance() throws IOException, InterruptedException { return new RedisRunner() .nosave() .randomDir() .randomPort() .run(); } }